{"record":{"id":"7c4aab8f2c5c6a6d","repo":"can1357/oh-my-pi","slug":"summary-exceeds-config-summaryhardlimit-bytes","errorCode":null,"errorMessage":"Summary exceeds ${config.summaryHardLimit} bytes","messagePattern":"Summary exceeds (.+?) bytes","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/commit/conventional/normalization.ts","lineNumber":217,"sourceCode":"\treturn joinFirstRest(`${past}${suffix}`, rest);\n}\n\n/** Normalize summary, body, and footers before final validation. */\nexport function postProcessCommitMessage(\n\tmessage: ConventionalCommit,\n\tconfig: ConventionalGenerationConfig,\n): ConventionalCommit {\n\tlet summary = normalizeCommitUnicode(message.summary);\n\tsummary = summary.replaceAll(\"\\r\", \" \").replaceAll(\"\\n\", \" \").split(/\\s+/).filter(Boolean).join(\" \");\n\tsummary = summary\n\t\t.trim()\n\t\t.replace(/[.;:]+$/g, \"\")\n\t\t.trim();\n\tsummary = lowercaseFirstToken(summary);\n\tsummary = normalizeSummaryVerb(summary, message.type);\n\tsummary = lowercaseFirstToken(summary.trim()).replace(/\\.+$/g, \"\").trim();\n\tif (Buffer.byteLength(summary) > config.summaryHardLimit) {\n\t\tthrow new Error(`Summary exceeds ${config.summaryHardLimit} bytes`);\n\t}\n\n\tconst body: string[] = [];\n\tfor (const raw of message.body) {\n\t\tlet detail = normalizeCommitUnicode(raw).replaceAll(\"\\r\", \" \").replaceAll(\"\\n\", \" \");\n\t\tdetail = detail\n\t\t\t.trim()\n\t\t\t.replace(/^[•\\-*+]+/, \"\")\n\t\t\t.trim()\n\t\t\t.split(/\\s+/)\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \");\n\t\tdetail = detail.replace(/[.;,]+$/g, \"\").trim();\n\t\tif (!detail) continue;\n\t\tconst first = firstCodePoint(detail);\n\t\tif (first && first === first.toLowerCase() && first !== first.toUpperCase()) {\n\t\t\tdetail = first.toUpperCase() + detail.slice(first.length);\n\t\t}","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/commit/conventional/normalization.ts#L199-L235","documentation":"postProcessCommitMessage enforces a hard byte limit on the commit summary (first line) after lowercasing, verb normalization, and punctuation trimming. If the summary still exceeds config.summaryHardLimit bytes, it throws instead of emitting an over-long commit subject (raised in postProcessCommitMessage, called by generateConventionalCommit, generateFastCommit, messageFromAnalysis, validateAndProcess).","triggerScenarios":"Calling any commit-message generation/validation entry point with a message whose normalized summary exceeds summaryHardLimit bytes — typically very long model-generated subjects, CJK/multibyte text (byte-length counts UTF-8 bytes, not characters), or a config with an unusually small hard limit.","commonSituations":"Models ignoring subject-length instructions, multibyte characters pushing byte counts over the limit while looking short, overly verbose generated summaries after scope prefixing, or tightened summaryHardLimit config.","solutions":["Truncate or rewrite the summary before calling post-processing (e.g. cut at word boundary under the limit)","Regenerate with prompt instruction to keep the subject short","Raise config.summaryHardLimit if your project allows longer subjects","Beware multibyte text: measure with Buffer.byteLength and trim to the byte budget"],"exampleFix":"// before\nconst message = await postProcessCommitMessage(raw, config);\n// after: pre-trim the summary\nconst limit = config.summaryHardLimit;\nlet summary = raw.summary;\nwhile (Buffer.byteLength(summary) > limit) summary = summary.slice(0, summary.lastIndexOf(\" \")).trim();\nconst message = await postProcessCommitMessage({ ...raw, summary }, config);","handlingStrategy":"validation","validationCode":"if (Buffer.byteLength(summary) > config.summaryHardLimit) {\n  summary = summary.slice(0, config.summaryHardLimit).trim();\n}","typeGuard":null,"tryCatchPattern":"try {\n  message = postProcessCommitMessage(raw, config);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"Summary exceeds\")) {\n    // regenerate with a brevity instruction or truncate the subject\n  }\n  throw err;\n}","preventionTips":["Instruct the model to keep subjects under ~72 characters","Account for UTF-8 multibyte expansion when measuring length","Pre-truncate long subjects at word boundaries before post-processing"],"tags":["validation","normalization","limits"],"backgroundTag":"size-limit-exceeded","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}