Yeachan-Heo/oh-my-codex · error · Error
catalog_manifest_missing
Error message
catalog_manifest_missing
What it means
readCatalogManifest locates the catalog manifest by probing templates/catalog-manifest.json, src/catalog/manifest.json, and dist/catalog/manifest.json under the package root; if none exists it throws catalog_manifest_missing. This protects callers from silently operating without a catalog.
Source
Thrown at src/catalog/reader.ts:26
['src', 'catalog', 'manifest.json'],
['dist', 'catalog', 'manifest.json'],
] as const;
let cachedManifest: CatalogManifest | null = null;
let cachedPath: string | null = null;
function resolveManifestPath(packageRoot: string): string | null {
for (const segments of MANIFEST_CANDIDATE_PATHS) {
const fullPath = join(packageRoot, ...segments);
if (existsSync(fullPath)) return fullPath;
}
return null;
}
export function readCatalogManifest(packageRoot: string = getPackageRoot()): CatalogManifest {
const path = resolveManifestPath(packageRoot);
if (!path) {
throw new Error('catalog_manifest_missing');
}
if (cachedManifest && cachedPath === path) return cachedManifest;
const raw = JSON.parse(readFileSync(path, 'utf8')) as unknown;
const manifest = validateCatalogManifest(raw);
cachedManifest = manifest;
cachedPath = path;
return manifest;
}
export function tryReadCatalogManifest(packageRoot: string = getPackageRoot()): CatalogManifest | null {
try {
return readCatalogManifest(packageRoot);
} catch {
return null;
}
}View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Verify which path exists: templates/catalog-manifest.json or src/catalog/manifest.json or dist/catalog/manifest.json under the root you pass
- If dist is incomplete, rebuild the package so dist/catalog/manifest.json is emitted
- If you pass packageRoot explicitly, point it at the actual package root containing the manifest
- Use tryReadCatalogManifest() if a null return is acceptable in your flow
Example fix
// before
const manifest = readCatalogManifest(someDir); // throws
// after
import { tryReadCatalogManifest } from './catalog/reader.js';
const manifest = tryReadCatalogManifest(someDir) ?? fallbackManifest; Defensive patterns
Strategy: fallback
Validate before calling
import { tryReadCatalogManifest } from './catalog/reader.js';
const manifest = tryReadCatalogManifest(root);
if (!manifest) { /* use fallback catalog or fail gracefully */ } Try / catch
try { readCatalogManifest(root); } catch (e) { if ((e as Error).message === 'catalog_manifest_missing') { /* fallback */ } throw e; } Prevention
- Ensure templates/ or dist/catalog/manifest.json ships with the package
- Prefer tryReadCatalogManifest for optional reads
- Verify custom packageRoot arguments in tests
When it happens
Trigger: Calling readCatalogManifest(packageRoot) (directly or via getCatalogCounts, contract, installableAgentNames) when the package root has none of the three candidate manifest files — typical for an incompletely built package or a wrong packageRoot argument.
Common situations: Running from a checkout before generating the manifest, a dist/ build that pruned catalog files, passing a custom packageRoot that doesn't contain the manifest, or packaging rules excluding JSON files.
Related errors
- catalog_manifest_invalid:${field}
- catalog_manifest_invalid:root
- catalog_manifest_invalid:schemaVersion
- catalog_manifest_invalid:skills
- catalog_manifest_invalid:agents
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/d1965be99faa2465.
Report an issue: GitHub.