Skip to content

build: disable Bun autoload of .env and bunfig.toml in compiled CLI#808

Merged
BYK merged 1 commit intomainfrom
build/bun-compile-autoload-flags
Apr 21, 2026
Merged

build: disable Bun autoload of .env and bunfig.toml in compiled CLI#808
BYK merged 1 commit intomainfrom
build/bun-compile-autoload-flags

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Apr 21, 2026

Summary

Pass autoloadDotenv: false and autoloadBunfig: false to Bun.build({ compile }) in script/build.ts so the compiled sentry binary no longer silently reads .env / .env.local / .env.production / bunfig.toml from the user's CWD at startup.

Why this matters

Without these flags, Bun auto-loads those files into process.env before our code runs. For a globally-installed CLI that users invoke from arbitrary project directories, this is a real footgun:

  • SENTRY_AUTH_TOKEN in a Next.js project's .env.local would override the stored OAuth token via getRawEnvToken() in src/lib/db/auth.ts.
  • SENTRY_ORG / SENTRY_PROJECT / SENTRY_DSN would pre-empt our DSN auto-detection in src/lib/resolve-target.ts.
  • Any other SENTRY_* var from src/lib/env-registry.ts (30+ of them) set in a project .env would leak into the CLI with no indication to the user.

Shell-level env vars continue to work unchanged. Users who want directory-scoped env vars should use direnv or source their .env explicitly — matching how gh, docker, etc. behave.

Verification

strace evidence (before/after with a hostile .env + bunfig.toml in CWD):

Probe Baseline Patched
Early openat("bunfig.toml") present gone
Early openat(".env") present gone
DSN detector's .env* walk present present (intentional — scans for SENTRY_DSN= URLs, not for runtime injection)

End-to-end behavior with .env containing SENTRY_ORG=injected-from-dotenv, SENTRY_PROJECT=injected-from-dotenv:

  • Baseline: picked up the injected values and sent them upstream (404 on nonexistent org).
  • Patched: correctly ignored the hostile .env, fell through to auto-detect and returned the usual "Could not auto-detect organization and project" hint.

Size: identical byte-for-byte to baseline (105,720,476 raw / 31,580,634 gzipped). The flags are runtime-only — they don't affect bundled content.

Startup (hyperfine --warmup 5 --runs 30 'sentry --version'):

Binary Mean Stdev
baseline 547.2 ms ±14.5 ms
patched 555.5 ms ±26.9 ms

Within noise — the win here is determinism and safety, not speed. Avoiding two openat syscalls at startup doesn't move the needle when the JS parse dominates.

What about bytecode: true?

Also explored as part of this work but not landed. Bytecode compilation would move JS parse cost from user-visible startup to build time (Bun docs report ~2× startup wins for tsc-scale apps). Unfortunately, as of Bun 1.3.11, bytecode: true crashes our ESM bundle at runtime:

TypeError: Expected CommonJS module to have a function wrapper.
If you weren't messing around with Bun's internals, this is a bug in Bun
Bun v1.3.11 (Linux x64)

The error fires before any of our code runs (stack points at Bun's module loader). Binary size grew only ~9 KB raw / ~1.3 KB gzipped, suggesting bytecode isn't even being embedded correctly — the flag just flips an assertion that trips the loader. Likely interacts with our two-step pipeline (esbuild → ESM bundle → Bun.build compile) that's unusual among bytecode use cases.

Closest-matching upstream issues (neither a clean match):

  • oven-sh/bun#21097 — "import.meta.env causes a cryptic TypeError in bun build --compile" (open)
  • oven-sh/bun#23490 — "While using compile command" crash (closed as duplicate)

Left a NOTE comment in compileTarget() so the next person doesn't re-try it without checking Bun's release notes first.

Without these flags, Bun silently loads `.env` / `.env.local` / `.env.production`
and `bunfig.toml` from the user's CWD into `process.env` before any of our code
runs. That's dangerous for a global CLI:

- `SENTRY_AUTH_TOKEN` in a project's `.env.local` would override the stored
  OAuth token via `getRawEnvToken()` in `src/lib/db/auth.ts`.
- `SENTRY_ORG` / `SENTRY_PROJECT` / `SENTRY_DSN` would pre-empt our DSN
  auto-detection flow in `src/lib/resolve-target.ts`.
- Any other `SENTRY_*` var from `src/lib/env-registry.ts` (30+ of them) set
  in a project `.env` would leak into the CLI with no indication.

Verified via strace: baseline binary opens `bunfig.toml` + `.env` before our
code runs; patched binary does not. End-to-end: baseline picked up
`SENTRY_ORG=injected-from-dotenv` from a hostile `.env` and queried it;
patched correctly ignored it and fell through to auto-detect.

Shell-level env vars continue to work unchanged. Users who want directory-
scoped env vars should use `direnv` or source their `.env` explicitly.

Also leaves a NOTE about `bytecode: true`: it would move JS parse cost from
startup to build time, but as of Bun 1.3.11 it crashes our ESM bundle at
runtime with "Expected CommonJS module to have a function wrapper" before
any of our code runs (likely related to oven-sh/bun#21097 / #23490). Revisit
once Bun's bytecode path stabilizes for our two-step esbuild-then-compile
pipeline.
@github-actions
Copy link
Copy Markdown
Contributor

Codecov Results 📊

138 passed | Total: 138 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 1769 uncovered lines.
✅ Project coverage is 95.63%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    95.63%    95.63%        —%
==========================================
  Files          281       281         —
  Lines        40462     40462         —
  Branches         0         0         —
==========================================
+ Hits         38692     38693        +1
- Misses        1770      1769        -1
- Partials         0         0         —

Generated by Codecov Action

@BYK BYK merged commit 3602840 into main Apr 21, 2026
23 checks passed
@BYK BYK deleted the build/bun-compile-autoload-flags branch April 21, 2026 23:28
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