react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

Invalid border width: undefined

Open joshkay opened this issue 8 months ago • 17 comments

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

joshkay avatar Mar 20 '25 18:03 joshkay

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",

joshkay avatar Mar 20 '25 18:03 joshkay

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.

zack avatar Mar 21 '25 19:03 zack

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?

Aguen13 avatar Mar 22 '25 12:03 Aguen13

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.

zack avatar Mar 22 '25 12:03 zack

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.

mdodge-ecgrow avatar Mar 24 '25 20:03 mdodge-ecgrow

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.

mdodge-ecgrow avatar Mar 25 '25 14:03 mdodge-ecgrow

Same problem here, after upgrade to 4.3, using Next.js 15 and React 19...

"@react-pdf/renderer": "^4.3.0",

kameikay avatar Mar 28 '25 03:03 kameikay

@mdodge-ecgrow which version are you using?

kameikay avatar Mar 28 '25 04:03 kameikay

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;

kameikay avatar Mar 28 '25 16:03 kameikay

@mdodge-ecgrow which version are you using?

In my previous post I said I was on 3.4.5.

mdodge-ecgrow avatar Mar 28 '25 17:03 mdodge-ecgrow

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.

thorivarnj avatar Apr 03 '25 08:04 thorivarnj

@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. Image

And it's due to this condition being constructed wrongly: Image

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: Image

Which makes it impossible for me to fix it fully without forking the @react-pdf library and fixing it myself.

DeviousM avatar Apr 07 '25 10:04 DeviousM

@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',
  }
}

DeviousM avatar Apr 07 '25 12:04 DeviousM

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.

kameikay avatar Apr 07 '25 12:04 kameikay

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

DeviousM avatar Apr 07 '25 13:04 DeviousM

@diegomura - is there either a plan to fix it or review the change I made?

DeviousM avatar May 19 '25 14:05 DeviousM

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]

mdodge-ecgrow avatar May 19 '25 19:05 mdodge-ecgrow

Running into this as well. Please merge @diegomura .

travisanderson avatar Jul 09 '25 00:07 travisanderson

Got a few more valid examples that break the border param detection

border: none

border: solid windowtext 1pt

old-faraon avatar Aug 26 '25 05:08 old-faraon