{"record":{"id":"167fc431bed2c338","repo":"santifer/career-ops","slug":"all-loaded-models-have-been-blacklisted-this-sessi","errorCode":null,"errorMessage":"All loaded models have been blacklisted this session.","messagePattern":"All loaded models have been blacklisted this session\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"openrouter-runner.mjs","lineNumber":286,"sourceCode":"    } 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    );\n  }\n  // Build the active (non-blacklisted) model list in rotation order\n  const active = models.filter(m => !blacklistedModels.has(m));\n  if (active.length === 0) throw new Error('All loaded models have been blacklisted this session.');\n\n  for (let attempt = 0; attempt < active.length; attempt++) {\n    const model = active[(modelIndex % active.length + attempt) % active.length];\n    activeModel = model;\n    process.stdout.write(`[model] ${model} ... `);\n\n    try {\n      const body = JSON.stringify({\n        model,\n        messages: [\n          buildCachedSystemMessage(systemPrompt),\n          { role: 'user', content: userMessage },\n        ],\n        max_tokens: MAX_TOKENS,\n      });\n\n      const controller = new AbortController();\n      const timerId = setTimeout(() => controller.abort(), MODEL_TIMEOUT_MS);","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/openrouter-runner.mjs#L268-L304","documentation":"callOpenRouter rotates through a list of free OpenRouter models, blacklisting any model that fails during the session. This error is thrown when every model in the loaded list has been blacklisted, so no candidates remain for the request. It indicates the runner exhausted its model pool, not that the request itself was malformed.","triggerScenarios":"Repeated calls to callOpenRouter in one session where each loaded model fails (timeouts, HTTP errors, empty responses) and is added to blacklistedModels; by the time a new request arrives, models.filter(m => !blacklistedModels.has(m)) returns an empty array.","commonSituations":"Long-running batch jobs that hammer free OpenRouter models until all hit rate limits or outages; an API key tier with very few free models that all fail quickly; a transient provider outage blacklisting the entire pool within one session.","solutions":["Create a new runner instance / clear blacklistedModels so models get another chance (failures may be transient)","Check OpenRouter status and your account's available free models; add more free model IDs to the loaded model list","Inspect why models are failing (log the per-model error before blacklisting) and fix the root cause, e.g. rate limiting or an invalid key","Reduce request rate / concurrency to stay under free-tier rate limits","Fall back to a different provider or paid model if free capacity is exhausted"],"exampleFix":"// before\nconst active = models.filter(m => !blacklistedModels.has(m));\nif (active.length === 0) throw new Error('All loaded models have been blacklisted this session.');\n// after\nlet active = models.filter(m => !blacklistedModels.has(m));\nif (active.length === 0 && models.length > 0) {\n  console.warn('[model] all models blacklisted; resetting blacklist for retry');\n  blacklistedModels.clear();\n  active = models.slice();\n}","handlingStrategy":"retry","validationCode":"// before calling\nconst active = runner.getModels().filter(m => !runner.isBlacklisted(m));\nif (active.length === 0) {\n  runner.resetBlacklist(); // or recreate the runner\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await callOpenRouter(prompt);\n} catch (e) {\n  if (e.message.includes('blacklisted')) {\n    runner.resetBlacklist();\n    return await callOpenRouter(prompt); // one retry with fresh pool\n  }\n  throw e;\n}","preventionTips":["Log each model's failure reason when blacklisting so root causes surface","Cap blacklist growth per session and reset it periodically","Keep the free-model list current with OpenRouter's catalog","Throttle request rate to stay under free-tier limits"],"tags":["openrouter","model-pool","fallback-exhausted","session-state"],"backgroundTag":"empty-result-set","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}