can1357/oh-my-pi · error · Error
Unknown changelog category: ${raw}
Error message
Unknown changelog category: ${raw} What it means
normalizeChangelogCategory maps a raw category string (case-insensitively) to the canonical Keep-a-Changelog categories: Added, Changed, Fixed, Deprecated, Removed, Security. Any other value throws. This guards the changelog section generation from model-invented categories.
Source
Thrown at packages/coding-agent/src/commit/conventional/markdown.ts:397
function stripCategoryPrefix(text: string): { text: string; category?: ConventionalDetail["changelogCategory"] } {
const match = text.match(CATEGORY_RE);
if (!match?.groups) return { text: text.trim() };
return {
text: (match.groups.text ?? "").trim(),
category: changelogCategory(match.groups.bracket ?? match.groups.prefix ?? ""),
};
}
function changelogCategory(raw: string): ConventionalDetail["changelogCategory"] {
const normalized = raw.trim().toLowerCase();
if (normalized === "breaking" || normalized === "breaking changes") return "Breaking Changes";
if (normalized === "added") return "Added";
if (normalized === "changed") return "Changed";
if (normalized === "fixed") return "Fixed";
if (normalized === "deprecated") return "Deprecated";
if (normalized === "removed") return "Removed";
if (normalized === "security") return "Security";
throw new Error(`Unknown changelog category: ${raw}`);
}
function stripWrappingQuotes(text: string): string {
const pairs: Record<string, string> = { '"': '"', "'": "'", "`": "`", "“": "”", "‘": "’" };
const stripped = text.trim();
return stripped.length >= 2 && pairs[stripped[0] ?? ""] === stripped.at(-1)
? stripped.slice(1, -1).trim()
: stripped;
}
function normalizeEscapedWhitespace(text: string): string {
if (!text.includes("\\")) return text;
const parts = text.split("`");
for (let index = 0; index < parts.length; index += 2) {
parts[index] = (parts[index] ?? "")
.replaceAll("\\r\\n", "\n")
.replaceAll("\\n", "\n")
.replaceAll("\\r", "\n")View on GitHub (pinned to 9690622007)
Solutions
- Constrain the changelog prompt to exactly the six Keep-a-Changelog categories
- Add the common alias to the normalization table if it appears frequently in your model's output
- Normalize/alias categories before parsing (e.g. 'features'->'added', 'bug fixes'->'fixed')
- Regenerate the analysis with a model that follows the changelog format
Example fix
// before: throws on 'Features'
const category = normalizeChangelogCategory("Features");
// after: alias first in prompt or pre-map
const aliases = { features: "added", fixes: "fixed", bugfixes: "fixed" };
const category = normalizeChangelogCategory(aliases[raw.toLowerCase()] ?? raw); Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = ["added","changed","fixed","deprecated","removed","security"];
if (!KNOWN.includes(raw.trim().toLowerCase())) {
raw = aliasMap[raw.trim().toLowerCase()] ?? "changed"; // or reject early
} Try / catch
try {
category = normalizeChangelogCategory(raw);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Unknown changelog category")) {
category = "Changed"; // safe bucket for model-invented categories
} else throw err;
} Prevention
- Pin the changelog prompt to exactly the six Keep-a-Changelog categories
- Maintain an alias map for recurring model inventions (features->added, fixes->fixed)
- Validate categories during parsing, not at render time
When it happens
Trigger: Parsing analysis markdown whose detail lines carry a category like 'Features', 'Bug fixes', 'Improvements', 'Performance', or a typo — anything outside the six known categories after normalization reaches the mapper.
Common situations: Model output using non-keep-a-changelog headings ('New', 'Bugs'), localized categories, or prompt examples that list categories not in the canonical set; older model outputs generated under a different changelog prompt.
Related errors
- No [Unreleased] section found in changelog
- Unknown changelog category: ${raw}
- No JSON payload found in response
- Line numbers in @@ header must be >= 1
- Line hint must be >= 1
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/004ed7157c78a3ce.
Report an issue: GitHub.