Skip to content

Transform fails on async arrow with rest param inside a conditional expression (VariableDeclarator id got SpreadElement) #1725

@itaihanski

Description

@itaihanski

Description

Bundling a module that contains an async arrow function with a rest parameter and a block body, placed as a branch of a conditional (ternary) expression, fails during Metro's transform step with:

SyntaxError: <file>: Property id of VariableDeclarator expected node to be of
a type ["LVal","VoidPattern"] but instead got "SpreadElement"

This is not a parse error. hermesParser.parse(code, { babel: true }) succeeds on the input; the failure happens later, while Metro's Babel transform processes the hermes-produced AST. It is a @babel/types builder validation, so it carries no source location and Metro prints no code frame.

Minimal reproduction

A module whose entire contents are:

const g = e => (e ? async (...r) => { return r } : 0);
export default { g };

Import it from the entry and bundle for any platform (e.g. npx expo export --platform ios, or metro build). It fails with the error above.

Every one of the following variants bundles fine — all four conditions are required to trigger it:

Variant Result
e ? async (...r) => { return r } : 0 ❌ fails
async (...r) => { return r } (no ternary) ✅ ok
e ? (...r) => { return r } : 0 (not async) ✅ ok
e ? async (...r) => r : 0 (concise body, no block) ✅ ok

So the trigger is precisely: async + rest parameter + block body + conditional-expression position.

Regression

The byte-identical input bundles successfully on Metro 0.82.x (Expo SDK 53 / RN 0.79) and fails on Metro 0.84.4 (Expo SDK 56 / RN 0.85.3). Pure toolchain bisect — only the Metro/@react-native/babel-preset/hermes-parser versions changed.

Analysis

  • hermes-parser parse stage succeeds ({ babel: true }).
  • The error is thrown from @babel/types while a transform builds a VariableDeclarator whose id is a SpreadElement — i.e. a node is synthesized incorrectly during the async-to-generator / parameter handling of the hermes AST.
  • Likely an interaction between hermes-parser's Babel AST output and @react-native/babel-preset's async transform, surfacing in metro-transform-worker.

Environment

  • metro 0.84.4
  • hermes-parser 0.33.3
  • react-native 0.85.3 (Expo SDK 56.0.9)
  • node v24.1.0, macOS
  • Default Metro config (Hermes parser enabled by default, inlineRequires on)

Expected

The module bundles successfully — the syntax is valid and runs natively on Hermes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions