[Docs] Workflow tool args parameter is undocumented; nested-array gotcha causes runtime errors
summary
the public workflows page at code.claude.com/docs/en/workflows.md doesn't document the args parameter. only mention of "args" in the entire doc is in the disableWorkflows setting line (line 228). meanwhile the in-tool description has explicit warnings about args marshalling that users only see if they paste a workflow script into a session. this surfaces as runtime errors like #63253.
the gap
grep -in args against the rendered doc returns one unrelated hit. the public doc covers: when to use, bundled workflows, ask claude to write one, ultracode, approve plan, save for reuse, resume, cost, turn off. it does NOT cover:
- the
argsparameter on the Workflow tool call - the
argsglobal available inside the script - the marshalling constraints (actual JSON vs stringified)
users hit the workflow scripting layer by accident (looking at the raw script after asking claude to write one) or by reading the in-tool description embedded in claude code itself.
what the in-tool description already says
args: any — the value passed as Workflow's args input, verbatim (undefined if not provided). Pass arrays/objects as actual JSON values in the tool call, NOT as a JSON-encoded string —args: ["a.ts", "b.ts"], notargs: "[\"a.ts\", ...]"(a stringified list reaches the script as one string, soargs.filter/args.mapthrow).
this warning is necessary for any user passing structured data into a workflow. omitting it from public docs means users only learn it by hitting #63253-style errors.
proposed insertion
after the "Save the workflow for reuse" section, before "How a workflow runs":
## Parameterize a workflow A workflow can accept structured input via theargsparameter on the tool call. The script reads it as a globalargsvariable. Passargsas actual JSON, not a JSON-encoded string: | | example | | --- | --- | | good |args: ["src/a.ts", "src/b.ts"]| | good |args: { files: ["a.ts", "b.ts"], target: "test" }| | bad |args: "[\"src/a.ts\", \"src/b.ts\"]"| A stringified list reaches the script as one string.args.filterandargs.mapthrow. Pass nested arrays inside objects as actual JS arrays, not as JSON-encoded substrings. Inside the script, reference args directly: ``js phase('Review') const findings = await parallel(args.files.map(f => () => agent(Review ${f}, { schema: FINDINGS_SCHEMA }) ))``
why it matters
#63253 is a real user hitting args.X.map undefined with no idea why. the in-tool warning isn't reaching them because they read the public docs page first. one paragraph in public docs prevents the class of bug.
happy to PR the change if there's a community-accessible docs repo.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗