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
- Rebuild the omp binary or npm bundle with the standard build script so embedded stats assets are included
- Build the stats client (packages/stats client build) before the omp bundle step so the archive exists at embed time
- Verify the build configuration actually enables client embedding (not a minimal/stripped build)
- 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
- Always run the stats client build before the omp bundle/compile step
- Verify the artifact after build (embedded archive present) before distributing
- Prefer official installers/npm bundles over hand-rolled minimal builds
- Keep build scripts in sync so the asset-embedding step cannot be silently skipped
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
- bundled Silver.ttf must parse
- utoken: zstd decode failed
- blob broker exposure failed to start
- Malformed embedded docs index: non-empty payload without a n
- Bundled agent "${agentName}" for vibe cli "${cli}" is unavai
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/da2fddbbaf0e02a3.
Report an issue: GitHub.