Skip to content

compiler: inline callback param in nested .map() hoisted out of scope, generating orphan reference #2816

@matheuspoleza

Description

@matheuspoleza

When JSX inside an array .map() includes an inline callback prop whose parameter shadows nothing, the compiler appears to hoist that parameter out of its closure, generating an orphan reference in the output.

Repro

function List({ items }: { items: { id: string }[] }) {
  let selected: string | null = null;
  return (
    <div>
      {items.map((env) => (
        <Row
          key={env.id}
          onPick={(v) => { selected = v ? env.id : null; }}
        />
      ))}
    </div>
  );
}

Actual

Runtime error on mount:

Uncaught ReferenceError: v is not defined

Inspecting the served source, the map+JSX gets flattened into a __conditional call that references v outside any enclosing scope:

__append(__el12, __conditional(
  () => collapsed.value[g.id],
  () => null,
  () => __conditional(() => v, () => env.id, () => null)
));

Renaming v to any other single identifier (next, n) reproduces the same issue with the new name — the compiler is hoisting the inline callback parameter regardless of the chosen identifier.

Expected

Either:

  • The map body is compiled with the inline callback preserved as a closure, so v stays in scope; or
  • A compile-time diagnostic explains why this pattern isn't supported.

Workaround

Extract the map body into a separate sub-component that receives explicit props (onPick, onCommit, etc). This gives the compiler a clean boundary and the issue disappears.

Environment

  • Vertz 0.2.64 (dev server)
  • macOS arm64, Node v22

Metadata

Metadata

Assignees

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