Skip to content

Bare ${X:-${Y}} (nested braced reference outside strings) is a parse error — VarRef regex stops at the first } #173

Description

@tobert

Found during the GH #95 lexer-overhaul census (PR #172); pre-existing and unchanged by the rewrite — reproduces identically on the old and new pipeline.

Repro

Y=fallback; echo ${X:-${Y}}
parse error:
1:27 [parse]: found '}' expected something else, expression, redirect, ...
  | Y=fallback; echo ${X:-${Y}}

Bash prints fallback.

Cause

The VarRef logos regex is \$\{[^}]+\} — it stops at the first }, so the input lexes as VarRef("${X:-${Y}") + RBrace, and the parser trips on the dangling brace. logos can't express nested-brace matching in a regex, so this isn't a one-character fix.

What already works (workarounds)

  • Quoted: echo "${X:-${Y}}"fallback. The in-string interpolation parser hand-rolls brace-depth matching (find_default_separator in parser.rs handles nesting), so the quoted form is fine.
  • Simple ref in the default: echo ${X:-$Y}fallback (no inner braces, regex is happy).

So the gap is narrow: a bare (unquoted) ${...} whose default word contains a braced reference.

Fix directions (not prescribing)

The post-#95 scanner (scan() in lexer.rs) already tracks ${...} regions with a brace-depth counter — that's how $((..)) inside a bare ${...} gets its loud ArithmeticInVarRef error. The same region tracking could hand logos a pre-delimited varref (or synthesize the token directly) so the regex's first-} limitation stops mattering. Alternatively a token-level repair pass could stitch VarRef + balanced tail back together, but that's the kind of adjacency-fishing #95 just removed.

Related context: ${X:-$((1+2))} in the same bare position is now a deliberate loud error (ArithmeticInVarRef, PR #172) rather than a silent marker leak. If nested braced refs become legal here, that error's message ("assign it to a variable first") stays the right guidance for the arithmetic case.

Severity: loud parse error (not corruption), but it's a bash-idiomatic form agents reach for, and the error message gives no hint that quoting fixes it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions