react-pdf
react-pdf copied to clipboard
Invalid border width: undefined
Describe the bug PDF fails to render after upgrading from 4.1.6 -> 4.3
Error: Invalid border width: undefined
at Object.resolveBorderShorthand (file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/stylesheet/lib/index.js:195:23)
at file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/stylesheet/lib/index.js:742:41
at file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/fns/lib/index.js:69:18
at resolveStyles (file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/stylesheet/lib/index.js:762:69)
at computeStyle (file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/layout/lib/index.js:715:12)
at file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/layout/lib/index.js:724:19
at Array.map (<anonymous>)
at file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/layout/lib/index.js:727:36
at Array.map (<anonymous>)
at file:///C:/Users/joshm/Development/project-phoenix/client/node_modules/@react-pdf/layout/lib/index.js:727:36
To Reproduce Don't have a case I can share currently as all code is private.
Desktop (please complete the following information):
- Windows 11
- Chrome
- React-pdf v4.3
Just reverting @react-pdf/renderer to 4.1.6 did not fix the issue.
I instead reverted all the following packages (not sure which one exactly causes the problem). Downgrading them all to what used to be in my package-lock.json resolved the error for now.
"@react-pdf/renderer": "4.1.6",
"@react-pdf/font": "3.0.1",
"@react-pdf/layout": "4.2.0",
"@react-pdf/pdfkit": "4.0.0",
"@react-pdf/primitives": "4.0.0",
"@react-pdf/reconciler": "1.1.3",
"@react-pdf/render": "4.0.2",
"@react-pdf/types": "2.7.0",
Having the same issue. Narrowed it down to border={0} in the line <Col textAlign="right" maxWidth={88} border={0}>. Removing the border={0} solved the error. It wasn't doing anything there, anyway.
Unfortunately we're also working on a close source repository, but am happy to share limited further context for the purpose of problem solving if needed.
I have started getting this error as well. I don't want to downgrade if I can help it.
Any chance this will be fixed soon?
Had to hunt down a few more instances of this problem yesterday as we have about a dozen large PDFs being generated. It all came down to border shorthands inline and in the styles. So like border: 0 also caused this problem. Replacing those got us unblocked.
I am encountering the same issue. I am using the addon with this package here: https://www.npmjs.com/package/@ag-media/react-pdf-table I narrowed it down to simply trying to use that with no styles even declared:
<Table key={'ingredients'}>
<TH>
<TD>Ingredients</TD>
</TH>
</Table>
So I had to downgrade react-pdf back to 3.4.5.
Just reverting @react-pdf/renderer to 4.1.6 did not fix the issue.
I instead reverted all the following packages (not sure which one exactly causes the problem). Downgrading them all to what used to be in my package-lock.json resolved the error for now.
"@react-pdf/renderer": "4.1.6", "@react-pdf/font": "3.0.1", "@react-pdf/layout": "4.2.0", "@react-pdf/pdfkit": "4.0.0", "@react-pdf/primitives": "4.0.0", "@react-pdf/reconciler": "1.1.3", "@react-pdf/render": "4.0.2", "@react-pdf/types": "2.7.0",
I reverted back @react-pdf/renderer and was still having the issue. Once I deleted 'package-lock.json' and 'node_modules' and re-ran 'npm i', the problem was fixed. Not sure if that was your issue or not.
Same problem here, after upgrade to 4.3, using Next.js 15 and React 19...
"@react-pdf/renderer": "^4.3.0",
@mdodge-ecgrow which version are you using?
I think I figured out the problem:
In @react-pdf/stylesheet/lib/index.js:
const BORDER_SHORTHAND_REGEX = /(-?\d+(\.\d+)?(in|mm|cm|pt|vw|vh|px|rem)?)\s(\S+)\s(.+)/;
const matchBorderShorthand = (value) => value.match(BORDER_SHORTHAND_REGEX) || [];
const resolveBorderShorthand = (key, value, container) => {
const match = matchBorderShorthand(`${value}`);
if (match) {
const widthMatch = match[1] || value;
const styleMatch = match[4] || value;
const colorMatch = match[5] || value;
const style = styleMatch;
const color = colorMatch ? transformColor(colorMatch) : undefined;
const width = widthMatch ? transformUnit(container, widthMatch) : undefined;
if (key.match(/(Top|Right|Bottom|Left)$/)) {
return {
[`${key}Color`]: color,
[`${key}Style`]: style,
[`${key}Width`]: width,
};
}
if (key.match(/Color$/)) {
return {
borderTopColor: color,
borderRightColor: color,
borderBottomColor: color,
borderLeftColor: color,
};
}
if (key.match(/Style$/)) {
if (typeof style === 'number')
throw new Error(`Invalid border style: ${style}`);
return {
borderTopStyle: style,
borderRightStyle: style,
borderBottomStyle: style,
borderLeftStyle: style,
};
}
if (key.match(/Width$/)) {
if (typeof width !== 'number')
throw new Error(`Invalid border width: ${width}`);
return {
borderTopWidth: width,
borderRightWidth: width,
borderBottomWidth: width,
borderLeftWidth: width,
};
}
if (key.match(/Radius$/)) {
const radius = value ? transformUnit(container, value) : undefined;
if (typeof radius !== 'number')
throw new Error(`Invalid border radius: ${radius}`);
return {
borderTopLeftRadius: radius,
borderTopRightRadius: radius,
borderBottomRightRadius: radius,
borderBottomLeftRadius: radius,
};
}
if (typeof width !== 'number')
throw new Error(`Invalid border width: ${width}`);
if (typeof style === 'number')
throw new Error(`Invalid border style: ${style}`);
return {
borderTopColor: color,
borderTopStyle: style,
borderTopWidth: width,
borderRightColor: color,
borderRightStyle: style,
borderRightWidth: width,
borderBottomColor: color,
borderBottomStyle: style,
borderBottomWidth: width,
borderLeftColor: color,
borderLeftStyle: style,
borderLeftWidth: width,
};
}
return { [key]: value };
};
When borderWidth is set to 0, the match becomes undefined and throws the error. Maybe the solution would be to set the width value to 0 inseted of undefined at:
// From:
const width = widthMatch ? transformUnit(container, widthMatch) : undefined;
// To:
const width = widthMatch ? transformUnit(container, widthMatch) : 0;
// Or:
const width = (widthMatch || widthMatch === 0) ? transformUnit(container, widthMatch) : undefined;
I have also encountered this issue in a project. I have tried downgrading to 4.1.6 but with no luck. I originally encountered the issue on version 4.3.0.
@diegomura, this seems to be quite a problematic issue that breaks the library on quite a common scenario, you might want to take a look at it.
Specific line in the source: https://github.com/diegomura/react-pdf/blob/ee5c96b80326ba4441b71be4c7a85ba9f61d4174/packages/stylesheet/src/resolve/borders.ts#L33C11-L33C16
It seems that overeagerness in ensuring the typings (throws on wrong type being supplied) caused the behavior that we're seeing now. Before, it used to just ignore that fact it seems (and worked just fine): https://github.com/diegomura/react-pdf/commit/24fe4bf894fff055121926488b30d0bf212a9c45#diff-53e669cd5f71028f1a732b34215801c5edd7057d5d0dd84f5d46914ad26855c8L13
Essentially, anytime there's a border with value 0 (and not "0"), it throws, because it can't compute a value of 0, instead of undefined.
And it's due to this condition being constructed wrongly:
In my setup after replacing all the border shorthands with longer versions, I still have an issue induced by the @ag-media/react-pdf-table library that internally does this:
Which makes it impossible for me to fix it fully without forking the @react-pdf library and fixing it myself.
@thorivarnj, @kameikay, @joshkay - I have published a temporary workaround until a fix is deployed under this NPM package: @deviousm/react-pdf-stylesheet-noborderproblem (version 6.1.2) .
You'll have to alias it in your building tool as a @react-pdf/stylesheet. In case of webpack it's set up in the resolve config.
resolve: {
alias: {
// TEMP: temporary fix for react-pdf: https://github.com/diegomura/react-pdf/issues/3130
'@react-pdf/stylesheet': '@deviousm/react-pdf-stylesheet-noborderproblem',
}
}
Thanks, @DeviousM.
My workaround was to set all the places where I was setting the border to 0 (or none), to 0.0001px. Visually, the border disappeared, as did the error.
I keep the version to 4.3.0.
Also, here's a PR fixing this issue and compatibility with @ag-media/react-pdf-table (and probably other people using border: 0 shorthand):
https://github.com/diegomura/react-pdf/pull/3145
@diegomura - is there either a plan to fix it or review the change I made?
Yes, can we please get this fixed. It is preventing me from upgrading to React 19.
npm warn peer react@"^16.8.0 || ^17.0.0 || ^18.0.0" from @react-pdf/[email protected]
Running into this as well. Please merge @diegomura .
Got a few more valid examples that break the border param detection
border: none
border: solid windowtext 1pt