can1357/oh-my-pi · error
Generated identifier is invalid (must be lowercase kebab-cas
Error message
Generated identifier is invalid (must be lowercase kebab-case, 2+ words)
What it means
parseGeneratedAgentSpec validates the trimmed identifier against IDENTIFIER_PATTERN, which requires lowercase kebab-case with 2+ words (at least one hyphen). An identifier like 'Reviewer', 'reviewer', or 'x' fails the pattern and throws this error. It keeps generated agent ids consistent with the filesystem/config naming conventions used for agents.
Source
Thrown at packages/coding-agent/src/modes/components/agents-hub.ts:188
}
function parseGeneratedAgentSpec(raw: string): GeneratedAgentSpec {
const parsed = JSON.parse(extractJsonObject(raw)) as Partial<GeneratedAgentSpec>;
if (!parsed || typeof parsed !== "object") {
throw new Error("Model output is not a JSON object");
}
if (
typeof parsed.identifier !== "string" ||
typeof parsed.whenToUse !== "string" ||
typeof parsed.systemPrompt !== "string"
) {
throw new Error("Model output is missing required fields (identifier, whenToUse, systemPrompt)");
}
const identifier = parsed.identifier.trim();
const whenToUse = parsed.whenToUse.trim();
const systemPrompt = parsed.systemPrompt.trim();
if (!IDENTIFIER_PATTERN.test(identifier)) {
throw new Error("Generated identifier is invalid (must be lowercase kebab-case, 2+ words)");
}
if (!whenToUse.toLowerCase().startsWith("use this agent when")) {
throw new Error("Generated whenToUse must start with 'Use this agent when...'");
}
if (!systemPrompt) {
throw new Error("Generated systemPrompt is empty");
}
return { identifier, whenToUse, systemPrompt };
}
function matchAgent(agent: HubAgent, query: string): boolean {
const text = `${agent.name} ${agent.description} ${SOURCE_LABEL[agent.source]} ${agent.overrideModel ?? ""}`;
return query
.trim()
.split(/\s+/)
.every(token => fuzzyMatch(token, text).matches);
}
View on GitHub (pinned to 9690622007)
Solutions
- Retry the generation; if it repeats, state the naming constraint (lowercase kebab-case, two or more words) explicitly to the architect/user prompt.
- Sanitize/derive the identifier yourself from the description before invoking creation, and pass it as guidance.
- If validating locally before persisting, apply the same IDENTIFIER_PATTERN check to catch bad ids early.
Example fix
// before (model output)
{"identifier":"CodeReviewer", ...}
// after
{"identifier":"code-reviewer", ...} Defensive patterns
Strategy: validation
Validate before calling
const IDENTIFIER_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)+$/;
function identifierOk(id: string): boolean {
return IDENTIFIER_PATTERN.test(id.trim());
}
if (!identifierOk(parsed.identifier)) parsed.identifier = slugify(parsed.description); Type guard
function isKebabCaseMultiWord(v: unknown): v is string {
return typeof v === "string" && /^[a-z0-9]+(-[a-z0-9]+)+$/.test(v);
} Try / catch
try {
const spec = parseGeneratedAgentSpec(raw);
} catch (err) {
if (err.message.startsWith("Generated identifier is invalid")) {
const fixed = { ...parsed(raw), identifier: slugify(parsed(raw).identifier) };
return parseGeneratedAgentSpec(JSON.stringify(fixed));
} throw err;
} Prevention
- State the kebab-case, 2+ word rule verbatim in the generation prompt with an example.
- Pre-normalize identifiers (slugify) before submitting specs for validation.
- Share the IDENTIFIER_PATTERN regex in client-side pre-validation.
When it happens
Trigger: #runAgentCreationArchitect receives a valid spec whose identifier violates the kebab-case/2-word rule — e.g. 'CodeReviewer' (uppercase), 'reviewer' (single word), 'code_reviewer' (underscore), or 'code--reviewer' style malformed ids.
Common situations: Models producing CamelCase or single-word names from the user's feature description; non-English descriptions leading to a single-token identifier; model echoing the user's verbatim agent name.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Model output is not a JSON object
- Model output is missing required fields (identifier, whenToU
- Generated whenToUse must start with 'Use this agent when...'
- Generated systemPrompt is empty
- Invalid skill name "${raw}". Use lowercase letters, digits,
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/de69c54374508eac.
Report an issue: GitHub.