Workflow tool: script body throws "meta is not defined", and passed args sometimes arrives as undefined

Open 💬 0 comments Opened Jul 7, 2026 by rhohn94

Summary

Two related bugs in the Workflow tool's script execution runtime, hit during real usage of the write-capable Workflow tier:

  1. A script that references the meta object anywhere in its body (the object declared via the required export const meta = {...} at the top of every Workflow script) throws ReferenceError: meta is not defined at runtime — even though normal JS module scoping means a top-level const binding stays in scope for the rest of the file.
  2. In a separate invocation using the script parameter (inline source) together with args, the script's args global came through as undefined inside the script body, despite a well-formed JSON object being passed as the args parameter in the same tool call.

Environment

  • Claude Code 2.1.172
  • macOS (Darwin), arm64
  • Workflow invoked both via Workflow({ name: <saved-workflow-file> }) and via Workflow({ 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.

View original on GitHub ↗