Skip to content

Commit 9f7bce8

Browse files
committed
fix(paths): skip pino-pretty transport in compiled binaries
The Pino logger unconditionally configured `transport: { target: 'pino-pretty' }` whenever stdout is a TTY. Pino transports spawn a worker that performs a dynamic `require.resolve('pino-pretty')` at runtime, which cannot resolve inside Bun's `/$bunfs/` virtual filesystem in `bun build --compile` binaries. As a result, every CLI command crashed on startup in a real terminal: error: unable to determine transport target for "pino-pretty" at I (/$bunfs/root/archon-linux-x64:7:35652) 100% of fresh binary installs were unusable. Piping output (e.g. `archon version | cat`) masked the bug because `isTTY` became false. Compiled binaries now always emit NDJSON. Detection is inlined here because `@archon/paths` has zero `@archon/*` dependencies; it checks both `import.meta.dir` (covers ESM compiled binaries) and `process.execPath` basename (covers CJS bytecode binaries where `import.meta.dir` is empty). Fixes #960
1 parent 8a44faa commit 9f7bce8

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

packages/paths/src/logger.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,36 @@ function getInitialLevel(): string {
4343
return 'info';
4444
}
4545

46+
/**
47+
* Detect whether the current process is running as a `bun build --compile`
48+
* binary. Inlined here because `@archon/paths` has zero `@archon/*` deps.
49+
*
50+
* pino-pretty cannot be loaded inside a compiled binary: pino transports spawn
51+
* a worker that does a dynamic `require.resolve('pino-pretty')`, which fails
52+
* inside Bun's virtual `/$bunfs/` filesystem and crashes the binary on startup.
53+
*/
54+
function isCompiledBinary(): boolean {
55+
const dir = import.meta.dir ?? '';
56+
if (dir.startsWith('/$bunfs/') || dir.startsWith('B:\\~BUN\\') || dir.startsWith('B:/~BUN/')) {
57+
return true;
58+
}
59+
const exec = process.execPath ?? '';
60+
const base = exec.split(/[/\\]/).pop() ?? '';
61+
const withoutExt = base.replace(/\.exe$/i, '').toLowerCase();
62+
return exec !== '' && withoutExt !== 'bun' && withoutExt !== 'node';
63+
}
64+
4665
/**
4766
* Uses pino-pretty when stdout is a TTY and NODE_ENV !== 'production';
4867
* outputs newline-delimited JSON otherwise.
68+
*
69+
* Compiled binaries always use NDJSON (pino-pretty transport cannot resolve
70+
* inside `/$bunfs/`).
4971
*/
5072
function buildLoggerOptions(): pino.LoggerOptions {
5173
const level = getInitialLevel();
52-
const usePretty = process.stdout.isTTY && process.env.NODE_ENV !== 'production';
74+
const usePretty =
75+
process.stdout.isTTY && process.env.NODE_ENV !== 'production' && !isCompiledBinary();
5376

5477
if (usePretty) {
5578
return {

0 commit comments

Comments
 (0)