can1357/oh-my-pi · error · Error
Markdown summary empty after normalization
Error message
Markdown summary empty after normalization
What it means
parseSummaryMarkdown takes the model's markdown summary, strips tags/heading markers/label prefixes/quotes, and collapses whitespace. If after all normalization nothing remains, the summary is unusable and this error is thrown (raised by parseSummaryMarkdown, used by generateSummaryFromAnalysis and summary).
Source
Thrown at packages/coding-agent/src/commit/conventional/markdown.ts:115
/** Parse summary output from markdown, XML-ish tags, JSON, or plain text. */
export function parseSummaryMarkdown(text: string): string {
if (!text.trim()) return "";
const json = tryJson(text);
if (isRecord(json)) {
for (const key of ["summary", "title", "message"]) {
const value = json[key];
if (typeof value === "string" && value.trim()) return stripTypePrefix(value);
}
}
const cleaned = cleanMarkdownText(text);
const tagged = extractTagLenient(cleaned, "summary");
let summary = tagged ?? cleaned;
summary = stripHeadingMarkers(summary);
summary = stripLabelPrefix(summary);
summary = stripWrappingQuotes(summary);
summary = summary.split(/\s+/).filter(Boolean).join(" ");
if (!summary) throw new Error("Markdown summary empty after normalization");
return stripTypePrefix(summary);
}
/** Parse a conventional analysis from llm-git's lenient markdown contract. */
export function parseConventionalAnalysisMarkdown(
text: string,
defaultType: CommitType = "chore",
): ConventionalAnalysis {
const payload = tryJson(text);
if (isRecord(payload)) return analysisFromMapping(payload, defaultType);
const lines = cleanMarkdownText(text).split(/\r?\n/);
let heading: { index: number; type: CommitType; scope: string | null; summary: string } | undefined;
let coerced: typeof heading;
for (let index = 0; index < Math.min(5, lines.length); index += 1) {
const line = lines[index] ?? "";
const candidate = stripHeadingMarkers(line);
const parsed = parseHeadingLine(candidate, false);
if (parsed) {View on GitHub (pinned to 9690622007)
Solutions
- Fix upstream empty responses first — a normalized-empty summary usually means the model returned nothing real
- Retry generation with the same prompt
- Log the raw model text before parsing to confirm what normalization consumed
- Verify the extraction picked the correct section from the model output
Example fix
// before
const summary = parseSummaryMarkdown(rawText);
// after: guard upstream
if (!rawText || !rawText.trim()) throw new Error("Model returned no summary text");
const summary = parseSummaryMarkdown(rawText); Defensive patterns
Strategy: validation
Validate before calling
if (!rawText || !rawText.trim()) throw new Error("No summary text from model"); Type guard
function isNonEmptyText(s: string | undefined | null): s is string {
return typeof s === "string" && s.trim().length > 0;
} Try / catch
try {
summary = parseSummaryMarkdown(raw);
} catch (err) {
if (err instanceof Error && err.message === "Markdown summary empty after normalization") {
logger.warn("Model summary normalized to empty", { raw: raw.slice(0, 200) });
}
throw err;
} Prevention
- Log raw model output when normalization empties it, to see what was consumed
- Fix empty-response issues upstream before touching the parser
- Retry generation instead of parsing empty input
When it happens
Trigger: Calling parseSummaryMarkdown with a string that normalizes to empty: an empty input, input consisting only of '<summary>...</summary>' tags wrapping nothing, or text made solely of markdown markers ('#', '**', quotes, whitespace).
Common situations: Upstream 'Empty model response' or reasoning-only output being passed through, the model echoing only formatting artifacts, or feeding the wrong field (e.g. reasoning text) as the summary.
Related errors
- Markdown analysis type(scope): summary heading not found
- Replacement text is not valid UTF-8: {err}
- V2 compaction stream parse failed: ${err instanceof Error ?
- ${source} response is missing credentials.
- auto-thinking: unparseable local classification: ${JSON.stri
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c9df5ed8a1086ae4.
Report an issue: GitHub.