Skip to content

fix(interpreter): diagnostics carry bash's "$0: line N:" prefix - #2630

Merged
chaliy merged 1 commit into
mainfrom
claude/diag-line-prefix
Oct 8, 2026
Merged

chaliy merged 1 commit into
mainfrom
claude/diag-line-prefix

Conversation

@chaliy

@chaliy chaliy commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

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

What changed

Shell diagnostics now carry bash's non-interactive prefix: the running script's name and line ($0: line N: ) instead of a bare bash: . This covers interpreter errors (command not found, arithmetic, redirects, readonly, set -u, failglob) and the shell builtins bash ships (cd, read, type, pushd, source, …). Coreutils-style builtins keep their own cat: missing: ... form, as on a real system.

  • A sourced file names itself; bash -c children print bash: line N:.
  • Bash::set_interactive(true) (used by the CLI REPL and Terminal) keeps the bash: msg form of bash -i.
  • source missing reports SCRIPT: line N: missing: No such file or directory; source with no operand exits 2 with bash's usage line.
  • Redirect failures on while/for/if/case ... done < f report the closing line.
  • Under set -u, a bare positional is named $2, as bash does.

Why

Agents read stderr to locate a failure. Bash's script.sh: line 12: points at the line; bashkit's bash: did not. It was also the largest stderr gap on the bash-oracle scoreboard.

Before / After

Before, every one of these lines started with bash: and no line number. After:

$ bashkit t.sh
ok
t.sh: line 2: nosuch: command not found. Did you mean: touch?
t.sh: line 3: cd: /nope: No such file or directory
$ bash t.sh
ok
t.sh: line 2: nosuch: command not found
t.sh: line 3: cd: /nope: No such file or directory

The "Did you mean" hint is a deliberate sandbox feature and stays.

bash-oracle on 106 cases: match 92 → 98, strict 71 → 89 (one each from #2622 SHLVL, now on main) (floors raised in floor.txt).

Risk

Diagnostic text changes, so callers that matched bash: ... exactly will see the new prefix. Lines starting bash: are rewritten at the single builtin dispatch point; the decision is recorded at the top of interpreter/mod.rs. Known remaining gaps are in knowledge/operations/limitations.md ("Diagnostic prefix"): compound commands without spans report a stale line, and functions from sourced files name the caller's file.

Checklist

  • Failing tests first: tests/integration/diagnostic_prefix_tests.rs (23 cases, expected text checked against bash 5.2)
  • cargo fmt, clippy -D warnings, integration (1431), lib (2933), bashkit-cli, bash_comparison --ignored
  • Knowledge: log.md, limitations.md, bash-oracle README

Generated by Claude Code

@chaliy chaliy self-assigned this Oct 8, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 8, 2026 •

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 8a800d1 Commit Preview URL

Branch Preview URL
Oct 08 2026, 04:34 AM

@chaliy
chaliy force-pushed the claude/diag-line-prefix branch 3 times, most recently from d50cd0d to 03702b8 Compare October 8, 2026 03:59
Shell diagnostics now read like non-interactive bash:
`SCRIPT: line 2: x: command not found`, `bash: line 1: type: h: not found`
under -c, instead of a bare `bash: `. The name is BASH_SOURCE[0] when a
file is being read (a sourced file names itself), else $0.

- Interpreter messages go through Interpreter::diag_prefix / diag.
- Bundled builtins keep their `bash: name:` / `name:` text; the builtin
  dispatch point rewrites the line start before redirects or streaming
  see it. Usage lines, coreutils-style builtins and execution plans are
  untouched.
- eval syntax errors read `$0: eval: line N:`; failglob, arithmetic and
  write-error messages honor $0.
- `source missing` ends with a newline and reports the missing path;
  `source` with no operand exits 2 with bash's usage line.
- Redirect failures on while/for/if/case report the closing line.
- `set -u` names a bare positional `$2` like bash.
- Child shells (bash -c, scripts by path) get their own name and lines.
- Bash::set_interactive (used by the CLI REPL and Terminal) keeps the
  `bash: msg` form of `bash -i`.

bash-oracle: match 92 -> 98, strict 71 -> 89 of 106 (with #2622) (floors raised).
@chaliy
chaliy force-pushed the claude/diag-line-prefix branch from 03702b8 to 8a800d1 Compare October 8, 2026 04:33
@chaliy
chaliy merged commit 06fd27a into main Oct 8, 2026
46 checks passed
@chaliy
chaliy deleted the claude/diag-line-prefix branch October 8, 2026 05:02
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