can1357/oh-my-pi · error · Error

Embedded stats client bundle missing. Rebuild the omp binary

Error message

Embedded stats client bundle missing. Rebuild the omp binary or npm bundle with embedded stats assets.

What it means

When the stats server runs with the embedded client enabled (USE_EMBEDDED_CLIENT), getEmbeddedClientDir() expects the client bundle archive to be baked into the binary/npm bundle at build time. If EMBEDDED_CLIENT_ARCHIVE is absent it throws, instructing the user to rebuild with embedded stats assets — the running artifact was built without the stats client inlined.

Source

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

	const extractRoot = path.resolve(outputDir);

	for (const [archivePath, file] of files) {
		const sanitizedPath = sanitizeArchivePath(archivePath);
		if (!sanitizedPath) continue;
		const destinationPath = path.resolve(extractRoot, sanitizedPath);
		if (!destinationPath.startsWith(extractRoot + path.sep)) {
			throw new Error(`Archive entry escapes extraction directory: ${archivePath}`);
		}
		await Bun.write(destinationPath, file);
	}
}

async function getEmbeddedClientDir(): Promise<string> {
	if (!USE_EMBEDDED_CLIENT) return STATIC_DIR;
	if (embeddedClientDirPromise) return embeddedClientDirPromise;

	if (!EMBEDDED_CLIENT_ARCHIVE) {
		throw new Error(
			"Embedded stats client bundle missing. Rebuild the omp binary or npm bundle with embedded stats assets.",
		);
	}

	embeddedClientDirPromise = (async () => {
		const bundleHash = Bun.hash(EMBEDDED_CLIENT_ARCHIVE).toString(16);
		const outputDir = path.join(EMBEDDED_CLIENT_DIR_ROOT, bundleHash);
		const markerPath = path.join(outputDir, "index.html");
		try {
			const marker = await fs.stat(markerPath);
			if (marker.isFile()) return outputDir;
		} catch {}

		await fs.rm(outputDir, { recursive: true, force: true });
		await fs.mkdir(outputDir, { recursive: true });
		await extractEmbeddedClientArchive(EMBEDDED_CLIENT_ARCHIVE, outputDir);
		return outputDir;
	})();

View on GitHub (pinned to 9690622007)

Solutions

  1. Rebuild the omp binary or npm bundle with the standard build script so embedded stats assets are included
  2. Build the stats client (packages/stats client build) before the omp bundle step so the archive exists at embed time
  3. Verify the build configuration actually enables client embedding (not a minimal/stripped build)
  4. As a stopgap, serve the client from a static directory instead of the embedded bundle if that mode is available

Example fix

// before
bun build ./src/cli.ts --compile --outfile omp   # client assets missing
// after
bun run build:stats-client && bun run build:binary  # embeds EMBEDDED_CLIENT_ARCHIVE
Defensive patterns

Strategy: validation

Validate before calling

import { EMBEDDED_CLIENT_ARCHIVE, USE_EMBEDDED_CLIENT } from './embedded-assets';
if (USE_EMBEDDED_CLIENT && !EMBEDDED_CLIENT_ARCHIVE) {
  console.error('This binary was built without embedded stats assets — rebuild with the full build script.');
}
const dir = await getEmbeddedClientDir();

Type guard

function hasEmbeddedAssets(a: typeof EMBEDDED_CLIENT_ARCHIVE): a is NonNullable<typeof EMBEDDED_CLIENT_ARCHIVE> {
  return typeof a === 'string' && a.length > 0;
}

Try / catch

try {
  const dir = await staticDir();
} catch (err) {
  if (err.message.includes('Embedded stats client bundle missing')) {
    console.error('Rebuild: bun run build:stats-client && bun run build (or reinstall an official omp artifact).');
  } else throw err;
}

Prevention

When it happens

Trigger: staticDir() → getEmbeddedClientDir() on a binary or npm bundle whose build pipeline did not embed the stats client archive (build script skipped the asset-embedding step, or an official artifact was built from a checkout lacking the built client).

Common situations: Installing a self-compiled omp built without running the full build (client assets not built first); a stripped-down build configuration; a version mismatch where the build script changed and the embedding step was dropped; running from a source checkout without building the stats client.

Related errors


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