{"record":{"id":"88d829cdf9e72fb0","repo":"santifer/career-ops","slug":"http-resp-status-t-slice-0-120","errorCode":null,"errorMessage":"HTTP ${resp.status}: ${t.slice(0, 120)}","messagePattern":"HTTP (.+?): (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"openrouter-runner.mjs","lineNumber":236,"sourceCode":"      max_tokens: MAX_TOKENS,\n    });\n    const ctrl = new AbortController();\n    const timerId = setTimeout(() => ctrl.abort(), MODEL_TIMEOUT_MS);\n    try {\n      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;","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/openrouter-runner.mjs#L218-L254","documentation":"Thrown inside the pinned-model branch of callOpenRouter() (openrouter-runner.mjs) when the OpenRouter POST returns a non-2xx status. The message includes the HTTP status and the first 120 chars of the response body so the caller can see OpenRouter's error detail. This is the pinned-model (CAREER_OPS_MODEL) path — it does not auto-rotate, so a non-OK response surfaces directly.","triggerScenarios":"CAREER_OPS_MODEL is set, the request reaches OpenRouter, but resp.ok is false: 400 (bad request/unsupported model), 401 (bad key), 402 (payment required), 404 (unknown model id), 429 (rate limit), or 5xx (OpenRouter upstream error).","commonSituations":"Pinned a model id that doesn't exist or was deprecated (404); free-tier quota hit (402/429); key revoked (401); model temporarily unavailable on OpenRouter's side (5xx).","solutions":["Read the status: 401 → fix the key; 404 → the pinned model id is wrong/deprecated, check https://openrouter.ai/models; 429 → wait or unpin to let rotation pick another model; 402 → the pinned model isn't free, pick a free one.","Unset CAREER_OPS_MODEL to fall back to automatic free-model rotation which skips failing models.","Verify the exact model id spelling (e.g. 'google/gemini-2.0-flash-exp:free').","Retry after a short delay for transient 5xx."],"exampleFix":"# before\nexport CAREER_OPS_MODEL=some/deprecated-model\n# throws HTTP 404: ...\n\n# after — let rotation choose, or pin a known-free model\nunset CAREER_OPS_MODEL\n# or\nexport CAREER_OPS_MODEL=google/gemini-2.0-flash-exp:free","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await callOpenRouter(systemPrompt, userMessage); // pinned path\n} catch (e) {\n  if (e.message.startsWith('HTTP ') && process.env.CAREER_OPS_MODEL) {\n    // pinned model failed — fall back to automatic rotation\n    delete process.env.CAREER_OPS_MODEL;\n    return await callOpenRouter(systemPrompt, userMessage);\n  }\n  throw e;\n}","preventionTips":["When pinning CAREER_OPS_MODEL, copy the exact id from https://openrouter.ai/models (note the :free suffix).","Prefer rotation over pinning unless you need a specific model — rotation skips failing models.","Handle 401/404/429 distinctly: fix key, fix model id, or back off.","Log the status+body snippet so the underlying OpenRouter error is visible."],"tags":["api","openrouter","http","configuration","pinned-model"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}