Skip to content

fix(template): don't treat ${VAR} as an unresolved token - #10

Merged
maharajamihir merged 1 commit into
mainfrom
mihir/shell-expansion-not-a-token
Aug 18, 2026
Merged

maharajamihir merged 1 commit into
mainfrom
mihir/shell-expansion-not-a-token

Conversation

@maharajamihir

Copy link
Copy Markdown
Contributor

What's wrong

find_unresolved_token matches any {word} shape — including the inside of a shell parameter expansion. That was harmless while command and [env] went unrendered, but #8 started rendering them, so shell syntax and labctl token syntax now share a document.

The result is that a recipe whose command contains ${LABCTL_RUN_ID} — or ${HOME}, or ${out} — is rejected at submit:

$ labctl run recipes/labctl_e2e.toml
Error: unresolved template token "{LABCTL_RUN_ID}" in "…echo \"run: ${LABCTL_RUN_ID}\"…"

${…} is shell parameter expansion and is never a labctl token, so this is a false positive, and it hits the common case: any non-trivial bash -c command. This is a regression from #8 (mine), found submitting a real recipe against the berlin registry.

The fix

Skip a { that is immediately preceded by $. The other expansion forms (${VAR:-default}, ${#arr[@]}) already fall out of the token scan on their non-identifier bytes — it's the plain ${NAME} case that collides.

The exemption is deliberately positional, not a blanket escape:

  • a genuine unresolved token elsewhere in the same string is still caught — echo ${HOME} {outputs.typo.path} still fails at submit;
  • a labctl token next to a shell expansion still renders — ${HOME}/{run.id} → ${HOME}/run_abc.

Both are covered by new tests, alongside a table of expansion forms that must round-trip untouched.

cargo test --all-features: 39 passed, 0 failed (8 PG-gated tests ignored as usual).

`find_unresolved_token` matches any `{word}`, which includes the inside of
a shell parameter expansion. That was harmless while `command` and `[env]`
went unrendered, but they are rendered now, so the two syntaxes share a
document — and a recipe whose command says `echo ${LABCTL_RUN_ID}` fails at
submit with:

    Error: unresolved template token "{LABCTL_RUN_ID}" in "..."

`${…}` is shell syntax, never a labctl token, so skip a `{` preceded by `$`.
The other expansion forms (`${VAR:-default}`, `${#arr[@]}`) already fall out
of the scan on their non-identifier bytes; this covers the plain `${NAME}`
case that doesn't.

The exemption is positional, not a blanket escape: a genuine unresolved
token elsewhere in the same string is still caught, and a labctl token
sitting next to a shell expansion still renders. Both are tested.

Found submitting a real recipe against the berlin registry.
@maharajamihir
maharajamihir merged commit b786585 into main Aug 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant