can1357/oh-my-pi · error
Malformed shipped docs index at ${embedPath}: payload withou
Error message
Malformed shipped docs index at ${embedPath}: payload without a newline separator. Rebuild the bundle. What it means
The shipped docs index embed is stored as a payload line plus a newline separator. readShippedEmbed decodes it and throws if decoding fails, meaning the bundled embed file exists but is structurally broken (no newline separating payload from index). This indicates a corrupted or badly built bundle.
Source
Thrown at packages/coding-agent/src/internal-urls/docs-index.ts:106
/**
* Prepacked npm package: the docs embed is written to `dist/docs-index.generated.txt`
* during `gen:bundle` (compiled binaries inline it via `PI_DOCS_EMBED` instead).
* SDK consumers importing `@oh-my-pi/pi-coding-agent/*` load TypeScript source, where
* the build-time placeholder is empty, so this shipped file is their only reachable
* corpus. Returns `null` when the file is absent (dev tree before a bundle build).
*/
function readShippedEmbed(): DocsIndex | null {
const embedPath = path.resolve(import.meta.dir, "../../dist/docs-index.generated.txt");
let raw: string;
try {
raw = readFileSync(embedPath, "utf8");
} catch (err) {
if (isEnoent(err)) return null;
throw err;
}
const decoded = decodeDocsIndex(raw);
if (decoded === null) {
throw new Error(
`Malformed shipped docs index at ${embedPath}: payload without a newline separator. Rebuild the bundle.`,
);
}
return decoded;
}
/** 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-emptyView on GitHub (pinned to 9690622007)
Solutions
- Reinstall/rebuild the package so the shipped docs embed is regenerated
- Verify embedPath points at the embed from the same version as the code
- As a fallback, rely on non-embedded docs loading (disk/network) if available
Example fix
// before (corrupted embed) # bundle/docs-index.embed (single truncated line) // after bun run build # regenerate the bundle and its docs embed
Defensive patterns
Strategy: fallback
Validate before calling
const raw = await Bun.file(embedPath).text()
if (raw.length > 0 && !raw.includes('\n')) throw new Error(`shipped docs embed corrupt at ${embedPath}`) Try / catch
try {
index = await readShippedEmbed()
} catch (err) {
if (String(err).includes('Malformed shipped docs index')) {
logger.warn('shipped docs embed corrupt; docs disabled', { embedPath })
return emptyIndex
}
throw err
} Prevention
- Verify bundle integrity after install (checksums)
- Don't hand-edit embed files inside the package
- Rebuild bundles rather than patching generated artifacts
When it happens
Trigger: Loading the docs index (getIndex) from the shipped embed file when its content has no newline separator — i.e. a truncated or incorrectly assembled embed at embedPath.
Common situations: Interrupted install/bundle step left a partial embed file; hand-edited or corrupted file in the package; version mismatch where a new reader reads an old embed format.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/bc81bdad6149d4f5.
Report an issue: GitHub.