{"record":{"id":"b341c7b1d3731657","repo":"santifer/career-ops","slug":"empty-response","errorCode":null,"errorMessage":"Empty response","messagePattern":"Empty response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"openrouter-runner.mjs","lineNumber":241,"sourceCode":"      const resp = await fetch(OPENROUTER_API_URL, {\n        method: 'POST',\n        headers: {\n          'Authorization': `Bearer ${key}`,\n          'Content-Type':  'application/json',\n          'HTTP-Referer':  'https://github.com/santifer/career-ops',\n          'X-Title':       'career-ops',\n        },\n        body,\n        signal: ctrl.signal,\n      });\n      if (!resp.ok) {\n        const t = await resp.text();\n        throw new Error(`HTTP ${resp.status}: ${t.slice(0, 120)}`);\n      }\n      const data = await resp.json();\n      if (data.error) throw new Error(data.error.message);\n      const content = data.choices?.[0]?.message?.content ?? '';\n      if (!content) throw new Error('Empty response');\n      console.log('OK');\n      const usage = normalizeOpenAIUsage(data.usage);\n      return { content, usage };\n    } catch (e) {\n      if (e.name === 'AbortError') throw new Error(`Pinned model timed out after ${MODEL_TIMEOUT_MS / 1000}s`);\n      throw e;\n    } finally {\n      clearTimeout(timerId);\n    }\n  }\n\n  const models = await loadFreeModels();\n  let lastError;\n\n  if (models.length === 0) {\n    throw new Error(\n      'No free OpenRouter models are available. Model loading may have failed, or your account currently has no free models.'\n    );","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/openrouter-runner.mjs#L223-L259","documentation":"Thrown in the pinned-model branch of callOpenRouter() when the HTTP call succeeded with no error object, but data.choices[0].message.content is empty (null, undefined, or empty string). This means the model returned a well-formed but contentless response — OpenRouter accepted the request and the model produced no output tokens.","triggerScenarios":"CAREER_OPS_MODEL is set, response is 2xx with no error, but the choices[0].message.content path resolves to '' or null. Common with content-filtered responses that return finish_reason without text, or a provider hiccup yielding zero output.","commonSituations":"Content filtered at the provider level (finish_reason: 'content_filter') returning empty text; model glitch; very rare provider routing issue; the prompt was malformed in a way that produced no generation.","solutions":["Retry once — empty responses are often transient single-call glitches.","Switch pinned model (CAREER_OPS_MODEL) to a different provider/model, or unset to use rotation which skips the failing model.","Inspect the full response (log data.choices[0]) to check finish_reason and any filter flags.","Simplify/shorten the prompt to rule out an input-shape problem."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await callOpenRouter(systemPrompt, userMessage);\n} catch (e) {\n  if (e.message === 'Empty response' && process.env.CAREER_OPS_MODEL) {\n    // empty content from pinned model — retry on rotation\n    delete process.env.CAREER_OPS_MODEL;\n    return await callOpenRouter(systemPrompt, userMessage);\n  }\n  throw e;\n}","preventionTips":["Retry once on empty responses — they're often transient.","Use rotation rather than a single pinned model so an empty response doesn't block the run.","Inspect finish_reason in the raw response to detect content-filter empties.","Simplify the prompt if empties recur on the same model."],"tags":["api","openrouter","llm","pinned-model","empty-response"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}