santifer/career-ops · error
Missing SCORE_SUMMARY block from model output
Error message
Missing SCORE_SUMMARY block from model output
What it means
The Gemini call succeeded and returned evaluationText, but it does not contain the '---SCORE_SUMMARY--- ... ---END_SUMMARY---' delimited block the parser regex (/---SCORE_SUMMARY---\s*([\s\S]*?)---END_SUMMARY---/) requires. The model drifted from the output contract: it ignored the delimiters, got truncated before closing the block (output token limit), declined the content, or a safety stop fired. The script logs the first 500 characters of the raw model output before throwing, which is the primary diagnostic.
Source
Thrown at batch-evaluate-gemini.mjs:253
console.log(`\n========================================`);
console.log(`🔄 Processing [${idx}]: ${companyHint} - ${titleHint}`);
console.log(`🔗 URL: ${url}`);
try {
const jdText = await scrapeUrl(browser, url);
if (!jdText || jdText.length < 100) {
throw new Error('Extracted text too short (likely blocked or empty)');
}
console.log(`🧠 Calling Gemini (${modelName})...`);
const evaluationText = await _evaluate(`URL: ${url}\n\n${jdText}`);
// Parse output
const summaryMatch = evaluationText.match(/---SCORE_SUMMARY---\s*([\s\S]*?)---END_SUMMARY---/);
if (!summaryMatch) {
console.error('Missing SCORE_SUMMARY block from model output:\n' + evaluationText.slice(0, 500));
throw new Error('Missing SCORE_SUMMARY block from model output');
}
const block = summaryMatch[1];
const extract = (key) => {
const m = block.match(new RegExp(`^\\s*${key}:\\s*(.+)$`, 'mi'));
return m ? m[1].trim() : 'unknown';
};
const company = extract('COMPANY');
const role = extract('ROLE');
const score = extract('SCORE');
const archetype = extract('ARCHETYPE');
const legitimacy = extract('LEGITIMACY');
// Save
mkdirSync(PATHS.reports, { recursive: true });
mkdirSync(PATHS.trackerAdditions, { recursive: true });
View on GitHub (pinned to 60398d6549)
Solutions
- Inspect the logged raw output slice: a refusal/safety message means change the input; text cut mid-sentence means truncation.
- Re-run the single entry: transient format drift often passes on retry.
- If truncated, shorten the JD text sent to the model or raise the output token limit.
- Pin a more instruction-following model (raise spend_tier) for batch runs.
- If you edited the prompt, restore the exact ---SCORE_SUMMARY--- / ---END_SUMMARY--- delimiters so prompt and parser regex match again.
Example fix
// before (prompt ends loosely) ...then give your verdict. // after (pin the contract in the prompt) ...then finish your response with exactly: ---SCORE_SUMMARY--- COMPANY: ... ROLE: ... SCORE: ... ARCHETYPE: ... ---END_SUMMARY---
Defensive patterns
Strategy: retry
Try / catch
let evaluationText;
for (let attempt = 0; attempt < 2; attempt++) {
evaluationText = await _evaluate(jd);
if (/---SCORE_SUMMARY---[\s\S]*?---END_SUMMARY---/.test(evaluationText)) break;
if (attempt === 1) {
fs.writeFileSync(`batch/raw-output-${Date.now()}.txt`, evaluationText); // quarantine for manual parse
throw new Error('Missing SCORE_SUMMARY block from model output');
}
} Prevention
- Keep the delimiter contract in one place: prompt and parser regex must use identical ---SCORE_SUMMARY---/---END_SUMMARY--- strings.
- Use a strongly instruction-following model for batch runs; save the cheap tier for triage.
- Cap JD input length so long postings cannot push the summary past the output limit.
When it happens
Trigger: A smaller/cheaper model tier ignoring delimiter formatting; output truncated by maxOutputTokens so ---END_SUMMARY--- never appears; the model refusing content it flags (personal data, suspicious JD text); the evaluation prompt edited so prompt delimiters and the parser regex no longer match; API safety settings blocking completion.
Common situations: Lowering spend_tier/model in config for cost and hitting weaker format adherence; very long JDs pushing the summary past the output limit; after hand-editing the evaluation prompt in modes/ the delimiter contract broke.
Related errors
- Gemini returned an invalid career-ops report: ${issues.join(
- Could not determine the rendered PDF page count from its pag
- wttj: /api/env payload has no JSON object
- wttj: /api/env payload is not valid JSON
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/e1c079252c4e1e14.
Report an issue: GitHub.