vercel-labs / vercel-labs/callscript

planToJs renders non-identifier arg keys as invalid JS

Open
#7 0 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.