Skip to content

fix(caps): declare missing capabilities surfaced while debugging the HTTP panic - #11

Merged
Ch4s3 merged 1 commit into
mainfrom
claude/bastion-http-panic-fix-dbd095
Aug 15, 2026
Merged

Ch4s3 merged 1 commit into
mainfrom
claude/bastion-http-panic-fix-dbd095

Conversation

@Ch4s3

@Ch4s3 Ch4s3 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • BastionServer imports Bastion, which requires Cap(IO.FileRead) and Cap(IO.FileWrite); neither was declared, so march main's capability-ceiling check hard-errors on any build that pulls this module in.
  • Bastion.ErrorOverlay imports Bastion.Dev, which requires Cap(IO.Mut); same gap.
  • Both are the same class of issue fixed in fix(caps): declare IO.Mut in Health and Metrics; 0.2.7 #10 and the IO.Mut fix in Bastion.Dev (0d23a77, 96c0ec8) — the capability-ceiling check is being rolled out module by module and these two hadn't been hit yet.

Context

Found while root-causing the reported "any HTTP request panics with non-exhaustive pattern match" bug. That panic's actual root cause was not in bastion — it turned out to be a stale March compiler toolchain on the debugging machine whose bundled stdlib/websocket.march still had a duplicate type Conn = Conn(...) declaration that a March compiler fix (upstream commit 6dc58ea1) had already removed. Re-syncing that toolchain resolved the panic; there is no bastion source change for it. These two capability declarations are a genuine, separate fix that forge check/forge build surfaced along the way.

Also found, but not fixed in this PR (separate root cause, tracked separately): a compiled Bastion HTTP server handles the first request fine but the process dies silently starting on the second request — reproduces with bare stdlib HttpServer.plug/listen, both threaded and sequential, so not a concurrency race. Likely a reference-counting gap where a closure's captured free variable isn't protected the same way the outer closure reference is.

Test plan

  • forge check — 80 files, 0 errors
  • forge build on a scaffolded app (forge bastion.new) depending on this branch — compiles clean
  • curl against the running server returns a real 200 OK on the first request

…ErrorOverlay

BastionServer imports Bastion, which requires Cap(IO.FileRead) and
Cap(IO.FileWrite); Bastion.ErrorOverlay imports Bastion.Dev, which
requires Cap(IO.Mut). Neither declared the capability, so march main's
capability-ceiling check now catches this as a hard error, matching the
same class of gap fixed in 0d23a77 and 96c0ec8.
@Ch4s3
Ch4s3 merged commit c70fb5f into main Aug 15, 2026
0 of 2 checks 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