different-ai/openwork · error · InterpreterRuntimeError
Cannot access '${name}' before initialization.
Error message
Cannot access '${name}' before initialization. What it means
Reading an identifier whose binding exists but is not yet initialized reproduces JavaScript's temporal dead zone (TDZ) as a ReferenceError. This occurs specifically for parameter default expressions that forward-reference a later parameter of the same function — the binding is registered but flagged initialized === false until its default is evaluated.
Source
Thrown at packages/codemode/src/interpreter/runtime.ts:3281
// anything else already present is a genuine duplicate declaration.
const existing = scope.get(name)
if (existing && existing.initialized !== false) {
throw new InterpreterRuntimeError(`Identifier '${name}' has already been declared.`, node)
}
scope.set(name, { mutable, value, initialized: true })
}
private getIdentifierValue(name: string, node: AstNode): unknown {
const binding = this.resolveBinding(name)
if (!binding) {
throw new InterpreterRuntimeError(`Unknown identifier '${name}'.`, node).as("ReferenceError")
}
// A parameter default that forward-references a later (not-yet-bound) parameter - JS TDZ.
if (binding.initialized === false) {
throw new InterpreterRuntimeError(`Cannot access '${name}' before initialization.`, node).as("ReferenceError")
}
return binding.value
}
private setIdentifierValue(name: string, value: unknown, node: AstNode): unknown {
const binding = this.resolveBinding(name)
if (!binding) {
throw new InterpreterRuntimeError(`Unknown identifier '${name}'.`, node).as("ReferenceError")
}
if (!binding.mutable) {
throw new InterpreterRuntimeError(`Cannot assign to constant '${name}'.`, node).as("TypeError")
}
binding.value = value
return valueView on GitHub (pinned to 2b7df46e8a)
Solutions
- Reorder parameters so defaults only reference earlier parameters: `function f(b = 2, a = b)`.
- Inline the default expression instead of referencing the later parameter.
- Compute the value inside the function body: `function f(a, b = 2) { a = a ?? b; }`.
Example fix
// before
function f(a = b, b = 2) { ... }
// after
function f(b = 2, a = b) { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// statically reject parameter defaults referencing later params
for (let i = 0; i < params.length; i++) {
for (let j = i + 1; j < params.length; j++) {
if (defaultRefs(params[i], params[j].name)) throw new Error(`default of '${params[i].name}' references later param '${params[j].name}'`);
}
} Try / catch
try {
const result = await interpret(src);
} catch (e) {
if (e instanceof InterpreterRuntimeError && e.message.endsWith("before initialization.")) {
// report a TDZ at e.node; suggest reordering parameter defaults
}
throw e;
} Prevention
- Only reference earlier parameters in parameter defaults.
- Inline default expressions instead of cross-referencing parameters.
- Handle the fallback inside the body with `a = a ?? b`.
- Surface e.node line/column to users when reporting.
When it happens
Trigger: A function parameter default referencing a parameter declared after it: `function f(a = b, b = 2) {}`. Evaluating the default for `a` reads `b` before it is bound.
Common situations: Porting JS code with out-of-order parameter defaults; LLM-generated function signatures that reference later parameters from earlier defaults.
Related errors
- Expected '${key}' to be a boolean.
- Failed to parse script as a Program node.
- String.${name} expects argument ${index + 1} to be a number.
- String.normalize expects the form "NFC", "NFD", "NFKC", or "
- String.replaceAll requires a regular expression with the glo
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/b764e03826611fa2.
Report an issue: GitHub.