Skip to content

parseExpensiMark throws TypeError when ExpensiMark emits a link without data-link-variant #830

Open

Description

@trackoor

parseExpensiMark throws TypeError: Cannot read properties of null (reading '1') on inputs where an email address is immediately followed by /, ?, or # and a URL (for example alice@example.com/https://example.com or alice@example.com/example.com).

Reproduction (repro.cjs):

npm install @expensify/react-native-live-markdown@0.1.372 expensify-common@2.0.229 html-entities@2.5.3
node repro.cjs
const Module = require("module");
const origLoad = Module._load;
Module._load = (req, ...rest) => (req === "react-native" ? { Platform: { OS: "web" } } : origLoad(req, ...rest));
global.__DEV__ = false;

const parseExpensiMark = require("@expensify/react-native-live-markdown/lib/commonjs/parseExpensiMark.js").default;

console.log(parseExpensiMark("alice@example.com/https://example.com"));

Or in src/__tests__/parseExpensiMark.test.ts:

test('email followed by slash and link', () => {
  expect('alice@example.com/https://example.com').toBeParsedAs([
    {type: 'link', start: 0, length: 17},
    {type: 'link', start: 18, length: 19},
  ]);
});

Actual output:

.../node_modules/@expensify/react-native-live-markdown/lib/commonjs/parseExpensiMark.js:180
        const isLabeledLink = node.tag.match(/data-link-variant="([^"]*)"/)[1] === 'labeled';
                                                                           ^

TypeError: Cannot read properties of null (reading '1')
    at dfs (.../node_modules/@expensify/react-native-live-markdown/lib/commonjs/parseExpensiMark.js:180:76)

Expected output:

[{"type":"link","start":0,"length":17},{"type":"link","start":18,"length":19}] (or [] when the reconstructed text does not match the input, rather than throwing an exception).

In expensify-common, ExpensiMark.modifyTextForUrlLinks handles URLs after an @ domain via this.replace(domainMatch[3], { filterRules: ['autolink'] }) without forwarding shouldKeepRawInput, so the second <a> tag has no data-link-variant attribute, and the non-null assertion in parseTreeToTextAndRanges (src/parseExpensiMark.ts line 186, node.tag.match(/data-link-variant="([^"]*)"/)![1]) throws.

Versions tested: @expensify/react-native-live-markdown@0.1.372 with expensify-common@2.0.229 on Node v26.13.0, and main (6cb3646, with both expensify-common@2.0.207 and 2.0.229).

Credit: https://ucsbplse.github.io/

Activity

  1. Mittalnew commented on Nov 14, 2026

    @Mittalnew

    Hi! I'd like to take this one. The crash comes from node.tag.match(/data-link-variant="([^"]*)"/)[1] in parseExpensiMark.ts when the <a> tag has no data-link-variant attribute. My plan is to handle a null match safely (fall back to a normal, non-labeled link) and add the alice@example.com/https://example.com case from the issue to parseExpensiMark.test.ts. Could you please assign it to me?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions