can1357/oh-my-pi · error · Error

Failed to build stats client (exit ${buildResult.exitCode})$

Error message

Failed to build stats client (exit ${buildResult.exitCode})${details}

What it means

The stats package's startServer() builds the bundled web client (build.ts) via `bun run build.ts` before serving the dashboard. If the build subprocess exits non-zero, ensureClientBuild throws this error, appending the captured build output so the underlying compile failure is visible.

Source

Thrown at packages/stats/src/server.ts:174

			cssStats.mtimeMs >= sourceMtime
		) {
			shouldBuild = false;
		}
	} catch {
		shouldBuild = true;
	}

	if (!shouldBuild) return;

	await fs.rm(STATIC_DIR, { recursive: true, force: true });

	console.log("Building stats client...");
	const packageRoot = path.join(import.meta.dir, "..");
	const buildResult = await $`bun run build.ts`.cwd(packageRoot).quiet().nothrow();
	if (buildResult.exitCode !== 0) {
		const output = buildResult.text().trim();
		const details = output ? `\n${output}` : "";
		throw new Error(`Failed to build stats client (exit ${buildResult.exitCode})${details}`);
	}

	const indexHtml = `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Usage Statistics</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="root"></div>
    <script src="index.js" type="module"></script>
</body>
</html>`;

	await Bun.write(path.join(STATIC_DIR, "index.html"), indexHtml);
};

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the build output appended below the error message — it contains the actual compiler/bundler failure
  2. Run `bun run build.ts` manually in packages/stats to reproduce and iterate on the fix
  3. Install dependencies (`bun install`) if this is a fresh clone
  4. Fix the underlying syntax/type/import error reported in the build output

Example fix

// before: server started without checking client build
await startServer({ port: 3000 })
// after: build once yourself to surface errors directly
$`bun run build.ts`.cwd("packages/stats").nothrow(); // inspect output before startServer
Defensive patterns

Strategy: try-catch

Validate before calling

const proc = Bun.spawnSync(["bun", "run", "build.ts"], { cwd: "packages/stats" });
if (proc.exitCode !== 0) throw new Error(proc.stderr.toString());

Try / catch

try {
  await startServer(opts);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Failed to build stats client")) {
    logger.error("stats client build failed", { cause: err });
    // surface err.message (includes build output) to the operator
  } else throw err;
}

Prevention

When it happens

Trigger: `bun run build.ts` inside packages/stats exits with a non-zero code — e.g. a TypeScript/bundler error, a missing dependency, a syntax error in client code, or a failed postbuild step.

Common situations: Editing client code in packages/stats and introducing a compile error; running the server in a fresh checkout where dependencies aren't installed; a broken or renamed build script; disk/permission issues in the output directory.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/8f3aa22cee0f4834. Report an issue: GitHub.