Skip to content

fix(parser): run commands before a later syntax error; quote/heredoc-aware $( ) end - #2513

Merged
chaliy merged 1 commit into
mainfrom
claude/project-thread-fwdh7i
Oct 6, 2026
Merged

chaliy merged 1 commit into
mainfrom
claude/project-thread-fwdh7i

Conversation

@chaliy

@chaliy chaliy commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Requested by Михайло · project thread

What changed

  1. Syntax errors no longer discard earlier lines. Like bash, commands on lines before the failing command run first, then the error is reported on stderr with exit 2. exit/set -e before the error still win, the EXIT trap runs, and bash -n keeps whole-script rejection. With nothing runnable before the error, exec() still returns Err(Parse) as before. Applies to top-level exec and child bash/sh.
  2. The end of $(...) is found correctly. One shared scanner (parser/subst_scan.rs) for the lexer and parse_word now skips parens inside quotes, escapes, backticks, comments and heredoc bodies. <<< and arithmetic << are not treated as heredocs.

Step 1 of the "closer to real bash" roadmap.

Why

Agents send long multi-line scripts. One typo near the end threw away every earlier command, unlike bash. And common shapes were rejected outright, e.g. a git commit -m "$(cat <<'EOF' ... (scope) ... EOF)" message containing a ), or $(echo ")").

Before / After

$ bashkit -c $'echo first\nif then'
before: Error: parse error ... (nothing ran)
after:  first
        bash: syntax error: parse error at line 2 ...   (exit 2)

$ bashkit -c $'x=$(cat <<\'E\'\nhello )\nE\n); echo "$x"'
before: bash: syntax error: ... unexpected token
after:  hello )

$ bashkit -c 'x=$(echo ")"); echo $x'
before: unterminated double quote
after:  )

The new spec cases pass bash_comparison_tests against real bash locally.

Risk

  • Medium
  • A script with a late syntax error now partly runs instead of failing up front. This matches bash, and tests that relied on the old behaviour were updated. Known gap, documented in knowledge/foundations/parser.md: a bare case pattern ) inside $(...) still closes early, the same as before.

Checklist

  • Tests added or updated (9 integration tests, 9 spec cases, scanner unit tests)
  • Backward compatibility considered

https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA


Generated by Claude Code

…aware $( ) end

Bash reads and runs a script line by line, so commands before a syntax
error execute and the error is reported afterwards (exit 2). Bashkit
rejected the whole script, losing all earlier work. Also find the end of
$(...) with a shared scanner aware of quotes, escapes, backticks,
comments and heredoc bodies; $(cat <<'E' ... ) ... E) and $(echo ")")
were cut at the inner paren.

Claude-Session: https://claude.ai/code/session_019aFikmptPc91Fj4N2iDXQA
@chaliy chaliy self-assigned this Oct 6, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 7eb4558 Commit Preview URL

Branch Preview URL
Oct 06 2026, 07:42 PM

@chaliy
chaliy merged commit 4f25d24 into main Oct 6, 2026
44 checks passed
@chaliy
chaliy deleted the claude/project-thread-fwdh7i branch October 6, 2026 20:00
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