can1357/oh-my-pi · error

Malformed embedded docs index: non-empty payload without a n

Error message

Malformed embedded docs index: non-empty payload without a newline separator. Rebuild the binary or bundle.

What it means

In compiled binaries and npm bundles the docs index is embedded in the binary itself. A non-empty embed with no newline separator cannot be decoded, so getIndex throws, flagging a broken build (truncated/corrupt embed) rather than silently returning an empty doc list.

Source

Thrown at packages/coding-agent/src/internal-urls/docs-index.ts:129

}

/** Empty index for when no docs corpus is reachable — degrades `omp://` instead of throwing ENOENT at callers. */
function emptyIndex(): DocsIndex {
	logger.warn(
		"omp:// docs corpus unavailable: no build-time embed, on-disk docs/ directory, or shipped dist embed found",
	);
	return { filenames: [], getBody: () => Promise.resolve(undefined) };
}

let index: DocsIndex | undefined;
function getIndex(): DocsIndex {
	if (index !== undefined) return index;
	// Populated embed in compiled binaries / npm bundle entrypoint. A non-empty
	// payload with no newline is a broken build (truncated/corrupt embed).
	if (docsEmbed.length > 0) {
		const decoded = decodeDocsIndex(docsEmbed);
		if (decoded === null) {
			throw new Error(
				"Malformed embedded docs index: non-empty payload without a newline separator. " +
					"Rebuild the binary or bundle.",
			);
		}
		index = decoded;
		return index;
	}
	// No build-time embed → running from TypeScript source. Prefer the shipped
	// embed file (`dist/docs-index.generated.txt`): it exists only in the packaged
	// npm tarball (or a dev tree that ran `gen:bundle`), so it authoritatively
	// identifies an installed package and avoids probing the consumer's
	// `node_modules/docs`, which `readDocsFromDisk()` would otherwise resolve to
	// and where a stray `docs` dir/package could shadow the real corpus. Fall back
	// to the on-disk `docs/` corpus for a genuine monorepo checkout, then degrade
	// to an empty index so a missing corpus never propagates ENOENT to callers.
	index = readShippedEmbed() ?? readDocsFromDisk() ?? emptyIndex();
	return index;
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Rebuild the binary/bundle (regenerates the embedded docs index)
  2. Re-download/reinstall the official binary instead of using a locally patched one
  3. Check the build pipeline step that embeds docs ran to completion
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const docs = getDocFilenames()
} catch (err) {
  if (String(err).includes('Malformed embedded docs index')) {
    logger.warn('embedded docs index corrupt; rebuild the binary', {})
    return []
  }
  throw err
}

Prevention

When it happens

Trigger: First call to getIndex (directly or via getDocFilenames/getEmbeddedDoc) when running a compiled binary or bundled build whose in-binary docsEmbed string is non-empty but malformed.

Common situations: A binary produced by a failed/interrupted compile-embed step; patching or post-processing the binary corrupted the embed; mixing an old binary with new reader code.

Understand the failure class

Related errors


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