vercel-labs / vercel-labs/callscript
planToJs renders non-identifier arg keys as invalid JS
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 86
- Forks
- 5
- Avg merge
- 28m
- Merged PRs (30d)
- 9
Description
Summary
planToJs in apps/web/lib/plan-to-js.ts renders call-step args object keys unquoted. A validated script whose args carry a non-identifier key (space, dot, or hyphen) renders as syntactically invalid JavaScript.
Details
args are validated by jsonValueSchema = z.record(z.string(), ...) in packages/callscript/src/schema.ts, so any string key is legal in a stored plan. But argsToJs emits object entries as `${k}: ${argsToJs(v)}` — the key raw. For example, args: { "foo bar": 1 } renders as:
const a = await svc.echo({ foo bar: 1 }, { reason: "r" });
which is a SyntaxError (Unexpected identifier 'bar'). Keys with dots (a.b) or hyphens (a-b) break the same way. Identifier keys (ok), numeric-string keys ("123"), reserved words (class), and unicode identifiers (ünï) are fine.
Impact
Low severity: planToJs is a display/authoring renderer (converts a stored plan back to its JS surface). It has no callers in the app today and its output is never executed. But the renderer's contract is to produce the readable JS form of any stored plan, and it produces garbage for a class of legal inputs — a latent correctness bug if the output is ever shown to a model or pasted back into an editor.
Fix
Quote keys that are not valid identifier names (reserved words are legal property names, so only identifier grammar needs checking). A fix is in progress on branch fix/plan-to-js-quote-non-identifier-keys in a fork.
Test coverage note
apps/web has no vitest wiring, so this renderer had no regression coverage. The fix adds a vitest seam and a regression test asserting planToJs output always parses as valid JS and round-trips non-identifier keys to the original value.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/web/lib/plan-to-js.ts and inspect argsToJs, then compare its accepted keys with jsonValueSchema in packages/callscript/src/schema.ts. Review the vitest seam and regression test described in the fix branch; done means the rendered output parses as JavaScript and preserves non-identifier keys when round-tripped.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 30/100