Workflow tool: script body throws "meta is not defined", and passed args sometimes arrives as undefined
Summary
Two related bugs in the Workflow tool's script execution runtime, hit during real usage of the write-capable Workflow tier:
- A script that references the
metaobject anywhere in its body (the object declared via the requiredexport const meta = {...}at the top of every Workflow script) throwsReferenceError: meta is not definedat runtime — even though normal JS module scoping means a top-levelconstbinding stays in scope for the rest of the file. - In a separate invocation using the
scriptparameter (inline source) together withargs, the script'sargsglobal came through asundefinedinside the script body, despite a well-formed JSON object being passed as theargsparameter in the same tool call.
Environment
- Claude Code 2.1.172
- macOS (Darwin), arm64
- Workflow invoked both via
Workflow({ name: <saved-workflow-file> })and viaWorkflow({ script: <inline source> })
Bug 1 — meta is not defined
Repro A — invoking a saved named workflow
A .claude/workflows/*.js file (a generic write-capable reference/example script) begins:
export const meta = {
name: 'write-capable-example',
tier: 'write-capable',
description: '...',
phases: [ /* ... */ ],
}
if (meta.tier === 'write-capable' && activeParadigm() !== 'Noir') {
throw new Error('write-capable workflows require the Noir paradigm...')
}
Invoking it via:
Workflow({ name: 'write-capable-example', args: { /* ... */ } })
fails immediately with:
Error: meta is not defined
at <anonymous> (workflow.js:55:9)
at workflow.js:395:1275
at runInContext (native)
...
Note: line 55 in the error does not correspond to line 55 of the actual persisted script (its meta declaration spans lines 1-11 and is syntactically valid, confirmed by reading the persisted script file back). The error appears to originate from the harness's own workflow.js wrapper around the user script, not from a syntax problem in the script itself.
Repro B — minimal inline script
export const meta = {
name: 'meta-scope-repro',
tier: 'write-capable',
description: 'Minimal repro for meta-is-not-defined',
phases: [{ title: 'Check' }],
}
if (meta.tier === 'write-capable') {
log('tier check passed')
}
phase('Check')
return { ok: true }
invoked via Workflow({ script: <above> }), also fails with:
Error: meta is not defined
at <anonymous> (workflow.js:2:9)
at workflow.js:147:1275
...
Removing every runtime reference to meta (keeping only the export const meta = {...} declaration itself) allows the script to proceed past this point.
Expected: export const meta = {...} is a normal top-level const declaration; per standard JS module semantics it should remain in scope for the rest of the script body, exactly as agent/phase/log/args do. The runtime appears to strip or relocate the meta declaration in a way that breaks this. This matters because gating script behavior on meta.tier/meta.name (e.g. a "fail closed unless this tier is appropriate for the active mode" check) is a natural, expected use of that object.
Bug 2 — args arrives as undefined when using inline script + args together
After removing the meta references (isolating bug 1), the next inline-script invocation:
export const meta = {
name: 'args-repro',
description: 'Minimal repro for args not arriving',
phases: [{ title: 'Execute' }],
}
phase('Execute')
const item = args.items[0]
log(`item: ${item.slug}`)
return { ok: true }
invoked via:
Workflow({
script: <above>,
args: { items: [{ slug: 'demo-item', description: '...' }] }
})
failed with:
Error: undefined is not an object (evaluating 'args.items[0]')
at <anonymous> (workflow.js:16:24)
at workflow.js:58:1275
...
implying args was undefined inside the script body, even though a well-formed JSON object was passed as the tool call's args parameter in the same request.
Note: I did not get a chance to further isolate whether this reproduces with a truly minimal payload in every case (e.g. whether it's specific to the size/shape of the args.items[...] content, or specific to combining script + args vs. name + args) — I stopped iterating after this surfaced to avoid burning further calls against what was clearly a broken path. Happy to help narrow it further if useful.
Impact
Both bugs make the documented "write-capable Workflow" pattern (multiple isolated-worktree agents fanning out from a caller-supplied args.items list, gated by a meta.tier check) fail on the very first lines of execution, for what should be ordinary top-level JS scoping/parameter-passing behavior. This blocks any reference implementation that both (a) reads meta for a paradigm/tier gate, and (b) accepts a caller-supplied item list via args.