Yeachan-Heo/oh-my-codex · error · Error
catalog_manifest_invalid:${field}
Error message
catalog_manifest_invalid:${field} What it means
This is the generic field-level validation failure from assertNonEmptyString inside validateCatalogManifest: the named field is missing, not a string, or whitespace-only. The message embeds the offending field path (e.g. skills[2].name, catalogVersion). It ensures every catalog manifest string field is a usable non-empty value.
Source
Thrown at src/catalog/schema.ts:39
export interface CatalogManifest {
schemaVersion: number;
catalogVersion: string;
skills: CatalogSkillEntry[];
agents: CatalogAgentEntry[];
}
const SKILL_CATEGORIES = new Set<CatalogSkillCategory>(['execution', 'planning', 'shortcut', 'utility']);
const AGENT_CATEGORIES = new Set<CatalogAgentCategory>(['build', 'review', 'domain', 'product', 'coordination']);
const ENTRY_STATUSES = new Set<CatalogEntryStatus>(['active', 'alias', 'merged', 'deprecated', 'internal']);
const REQUIRED_CORE_SKILLS = new Set(['autopilot', 'ralplan', 'team', 'ultragoal']);
function isObject(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function assertNonEmptyString(value: unknown, field: string): asserts value is string {
if (typeof value !== 'string' || value.trim() === '') {
throw new Error(`catalog_manifest_invalid:${field}`);
}
}
export function validateCatalogManifest(input: unknown): CatalogManifest {
if (!isObject(input)) throw new Error('catalog_manifest_invalid:root');
if (typeof input.schemaVersion !== 'number' || !Number.isInteger(input.schemaVersion)) {
throw new Error('catalog_manifest_invalid:schemaVersion');
}
assertNonEmptyString(input.catalogVersion, 'catalogVersion');
if (!Array.isArray(input.skills)) throw new Error('catalog_manifest_invalid:skills');
if (!Array.isArray(input.agents)) throw new Error('catalog_manifest_invalid:agents');
const seenSkills = new Set<string>();
const skills: CatalogSkillEntry[] = input.skills.map((entry, index) => {
if (!isObject(entry)) throw new Error(`catalog_manifest_invalid:skills[${index}]`);View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Read the field path in the message and open the manifest at that entry
- Set the field to a non-empty string (correct category/status values per the schema)
- Regenerate the manifest with the official generator rather than editing by hand
- Add a CI check that runs validateCatalogManifest on the built manifest
Example fix
// before
{ "name": " ", "category": "execution", "status": "active" }
// after
{ "name": "autopilot", "category": "execution", "status": "active" } Defensive patterns
Strategy: validation
Validate before calling
import { validateCatalogManifest } from './catalog/schema.js';
validateCatalogManifest(JSON.parse(readFileSync(path, 'utf8'))); // catch before shipping Type guard
function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.trim() !== ''; } Try / catch
try { readCatalogManifest(root); } catch (e) { if ((e as Error).message.startsWith('catalog_manifest_invalid:')) { /* report field path, fix manifest */ } throw e; } Prevention
- Run validateCatalogManifest in CI against built manifests
- Generate manifests with tooling, not by hand
When it happens
Trigger: A catalog manifest JSON where any string field validated via assertNonEmptyString (catalogVersion, skills[i].name/category/status, agents[i].name/category/status) is null, a number, an empty string, or whitespace.
Common situations: Hand-editing catalog-manifest.json and leaving a field blank, templating bugs that emit empty placeholders, or manifest generators skipping fields for some entries.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- catalog_manifest_invalid:root
- catalog_manifest_invalid:schemaVersion
- catalog_manifest_invalid:skills
- catalog_manifest_invalid:agents
- catalog_manifest_invalid:skills[${index}]
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/214eb775129b1cca.
Report an issue: GitHub.