Yeachan-Heo/oh-my-codex · error · Error
catalog_manifest_invalid:agents[${index}]
Error message
catalog_manifest_invalid:agents[${index}] What it means
Each element of the agents array must be a plain JSON object; this error names the index of the first element that is not (string, number, null, or array). It mirrors the skills[i] object check during the agents mapping loop.
Source
Thrown at src/catalog/schema.ts:93
: undefined;
if ((entry.status === 'alias' || entry.status === 'merged') && !canonical) {
throw new Error(`catalog_manifest_invalid:skills[${index}].canonical`);
}
return {
name,
category: entry.category as CatalogSkillCategory,
status: entry.status as CatalogEntryStatus,
canonical,
core: entry.core === true,
internalRequired: entry.internalRequired === true,
};
});
const seenAgents = new Set<string>();
const agents: CatalogAgentEntry[] = input.agents.map((entry, index) => {
if (!isObject(entry)) throw new Error(`catalog_manifest_invalid:agents[${index}]`);
assertNonEmptyString(entry.name, `agents[${index}].name`);
assertNonEmptyString(entry.category, `agents[${index}].category`);
assertNonEmptyString(entry.status, `agents[${index}].status`);
if (!AGENT_CATEGORIES.has(entry.category as CatalogAgentCategory)) {
throw new Error(`catalog_manifest_invalid:agents[${index}].category`);
}
if (!ENTRY_STATUSES.has(entry.status as CatalogEntryStatus)) {
throw new Error(`catalog_manifest_invalid:agents[${index}].status`);
}
const name = entry.name.trim();
if (seenAgents.has(name)) throw new Error(`catalog_manifest_invalid:duplicate_agent:${name}`);
seenAgents.add(name);
const canonical = typeof entry.canonical === 'string' && entry.canonical.trim() !== ''
? entry.canonical.trim()
: undefined;View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Replace the offending element with a full agent entry {name, category, status}
- Regenerate the manifest
- Validate JSON in an editor with schema support while editing
Example fix
// before
"agents": ["builder"]
// after
"agents": [ { "name": "builder", "category": "build", "status": "active" } ] Defensive patterns
Strategy: validation
Validate before calling
if (!raw.agents.every((a: unknown) => typeof a === 'object' && a !== null && !Array.isArray(a))) { /* fix entries */ } Type guard
const isEntry = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);
Prevention
- Never use bare string agent names in the manifest
- Use shared entry-building helpers when generating
When it happens
Trigger: An agents array containing a bare string agent name or null at the reported index.
Common situations: Shorthand agent lists or copy-paste from docs that list names without structure.
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:agents[${index}].category
- catalog_manifest_invalid:agents[${index}].status
- catalog_manifest_invalid:duplicate_agent:${name}
- catalog_manifest_invalid:agents[${index}].canonical
- catalog_manifest_invalid:${field}
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/704546c5c31e9c87.
Report an issue: GitHub.