Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions