Skip to content

fix: resolve dynamic # imports on Bun dev and gate every release - #1600

Merged
vivek7405 merged 4 commits into
mainfrom
fix/bun-dynamic-alias-import
Oct 7, 2026
Merged

vivek7405 merged 4 commits into
mainfrom
fix/bun-dynamic-alias-import

Conversation

@vivek7405

Copy link
Copy Markdown
Collaborator

Fixes the 0.8.85/0.8.86 regressions from #1584 and adds a release gate. Refs #1575.

  • file:/ ENOENT on a dynamic # import (Crisp /projects/<id> and provisioning 500). A Bun runtime onResolve result reaches a dynamic import() as a broken file:/... path. The alias resolver is gone; the app's # specifiers are rewritten to absolute paths when a module's source is loaded (the app-source and seed plugins), which still keeps a new file next to a server module resolvable.
  • Poisoned Bun transpiler cache. Includes Run the Bun dev child with the transpiler cache off #1596 (dev child runs with the cache off) and empties Bun's on-disk transpiler cache once per machine on the first WebJs server at this version, so entries 0.8.85/0.8.86 wrote stop breaking webjs start and in-process servers.
  • Release gate scripts/release-gate.mjs, documented in framework-dev.md: packs core/server/cli and runs them in a fresh --db postgres scaffold on Bun and Node (every page, sign up + sign in/out x3 with a signed-in page reading the current user and no redirect loop, a bound form action, headers(), a *.server.ts with relative imports via static and dynamic # imports, a >50KB module, the reload stress, all again after edits, webjs check/typecheck, webjs start on Bun after a 0.8.86 run warmed the cache, and the app again from a second path), the website from a second worktree with a warm cache, and Crisp downstream (server + browser suites, /, /dashboard, provisioning chain, createProject, /projects/<id>, before and after edits).

Gate: 52/52 on the full run (scaffold Bun + Node, website, Crisp) plus 22/22 on the Bun stage after the cache changes. Against main (0.8.86 + #1591) the same gate fails the dynamic import, request context and bound form action checks.

Local suites: npm test 5006 pass (1 timing flake under load, passes alone), Bun matrix 0 genuine failures except two timing flakes under load that pass when run alone, browser 981/981 Chromium + WebKit, Firefox 1 known-flaky scroll test that passes on rerun.

https://claude.ai/code/session_01SZ72LSPAo4NvYvBDSD6RLo

vivek7405 and others added 4 commits October 7, 2026 20:21
A Bun runtime onResolve result reaches a dynamic import() as a broken
file:/ path, so 0.8.85 and 0.8.86 answered 500 for any server module
with relative imports reached through await import('#...'), which is
how Crisp provisions projects. The # alias is now rewritten to an
absolute path when the module source is loaded, which keeps a new file
next to a server module resolvable without touching resolution. The
stress test now runs the app's own copies of the packages and adds the
dynamic-import case.

Refs #1575

Claude-Session: https://claude.ai/code/session_01SZ72LSPAo4NvYvBDSD6RLo
0.8.85 and 0.8.86 passed every unit suite and still broke real Bun
apps. The gate packs core, server and cli, runs a fresh postgres
scaffold on Bun and Node through page renders, sign-up and log-in, a
bound form action, request context and a server module reached by a
dynamic # import, before and after the agent-style reload stress, and
smoke-tests Crisp downstream with the candidate swapped in.

Claude-Session: https://claude.ai/code/session_01SZ72LSPAo4NvYvBDSD6RLo
Bun caches the transpile of every source over 50KB on disk, keyed by
content, with the paths a Bun.plugin onResolve returned baked in. The
dev alias resolver (#1575) returns absolute paths, so a large app module
was pinned to the checkout that first ran `webjs dev`: any other copy
of the same file (a worktree, a moved app, a later `webjs start`)
imported from that old directory, a 500 once it was gone and the wrong
code while it was not. It made the website home page 500 on Bun in
every local worktree. Bun reads the setting at startup, so the
supervisor sets it on the child.

Claude-Session: https://claude.ai/code/session_01SZ72LSPAo4NvYvBDSD6RLo
…ilds

Those versions baked broken file:/ import paths into Bun's on-disk
transpiler cache, keyed by the file's content, so an unchanged module
kept failing after the fix (webjs start, or any process with the cache
on). The first WebJs server on Bun now empties that cache once per
machine. The release gate warms a cache with 0.8.86 first, checks
webjs start on Bun, signs in and out repeatedly with a signed-in page
that reads the current user, and runs the app and the website again
from a second path with the cache warm.

Refs #1575

Claude-Session: https://claude.ai/code/session_01SZ72LSPAo4NvYvBDSD6RLo
@pilots-run

pilots-run Bot commented Oct 7, 2026

Copy link
Copy Markdown

Preview for 742583d was not built: compose file has unsupported keys

Next: fix the listed keys in the compose file

@vivek7405
vivek7405 merged commit eefd347 into main Oct 7, 2026
9 of 11 checks passed
@vivek7405
vivek7405 deleted the fix/bun-dynamic-alias-import branch October 7, 2026 15:24
vivek7405 added a commit that referenced this pull request Oct 7, 2026
#1600 made the fixture copy the framework packages instead of linking
them, but the copies lost their hoisted dependencies, so on Bun the
server could not load amaro (Bun has no built-in TS stripper) and the
dev server never came up. The Bun matrix failed on every PR since. The
fixture now links the repo's third-party packages beside the copies,
as a real install would place them; only framework packages stay copied.

Claude-Session: https://claude.ai/code/session_01SZ72LSPAo4NvYvBDSD6RLo

Co-authored-by: t <t@t>
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