Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

ArrayPush(N): local not in scope when pushing onto a const array initialised with an object literal (blocks TanStack Router SSR)

Open
#12,742 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
56/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
rust, typescript
Domain
compilers

Research direction

Start at the LLVM lowering path that handles ArrayPush and reproduce the failure with the TypeScript function in the issue; compare it with the working let variant. Trace how the array local is registered and kept in scope for the push operation. Done means the const example compiles and runs with output 2, while the documented working variants still compile.

Written by the indexing model from the issue text.

Description

Perry fails to compile a function that pushes onto a const array whose initialiser holds an object literal:

function f() {
  const s = [{ v: 1 }]
  s.push({ v: 2 })
  return s.length
}
console.log(f())
$ perry compile repro.ts -o repro
Error compiling module 'repro.ts' (…/repro.ts) with --backend llvm: lowering function 'f': lowering body of 'f': ArrayPush(1): local not in scope
✗ ENTRY MODULE FAILED TO COMPILE — REFUSING TO LINK

Node prints 2.

Small changes make it compile:

  • let s = [{ v: 1 }]
  • const s: {v: number}[] = [], then push
  • s[s.length] = { v: 2 } instead of push

Where it shows up. This isn't contrived. It's how TanStack Router's route matcher keeps its depth-first search stack. getNodeMatch in @tanstack/router-core (1.171.34, dist/esm/new-process-route-tree.js) starts with

const stack = [{ node: segmentTree, index: 1, skipped: 0, statics: 0, dynamics: 0, optionals: 0 }]
while (stack.length) {
  const frame = stack.pop()
  …
  stack.push({ … })
}

Every TanStack Router and TanStack Start app runs this on each request. So a server-rendering bundle from either one can't compile today. In our case, an SSR render bundle failed with ArrayPush(12121): local not in scope in getNodeMatch, and the full TanStack Start server got 111 of 113 modules through codegen before stopping on the same error. A worklist seeded with one root object is a common way to write tree traversals, so other code probably hits it too.

Environment: macOS 26.3.1 arm64, --backend llvm.

  • Perry 0.5.1520 (npm @perryts/perry): fails as above.
  • main at 7cbfde8 (0.5.1659, built 2026-10-17 with LLVM 22.1.8): same error (checked with --no-link); the let variant compiles.
Dominant language
Rust
Stars
4.9k
Forks
166
Avg merge
3h 23m
Merged PRs (30d)
911

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from PerryTS/perry

All issues in PerryTS/perry

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.