{"record":{"id":"1a187bb0a9d29d91","repo":"santifer/career-ops","slug":"no-free-openrouter-models-are-available-model-loa","errorCode":null,"errorMessage":"No free OpenRouter models are available. Model loading may have failed, or your account currently has no free models.","messagePattern":"No free OpenRouter models are available\\. Model loading may have failed, or your account currently has no free models\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"openrouter-runner.mjs","lineNumber":257,"sourceCode":"      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    );\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 },","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/openrouter-runner.mjs#L239-L275","documentation":"Thrown by callOpenRouter() after loadFreeModels() returns an empty array — the model list loaded but contained zero free models. This is distinct from a fetch failure (error 67): the API call succeeded, it just yielded nothing usable. Without any models, the rotation loop has nothing to iterate, so it fails immediately.","triggerScenarios":"loadFreeModels() returns []: OpenRouter's /models endpoint answered 2xx but no models matched the free-tier filter, or the account/region currently has no free models available. The `if (models.length === 0)` guard throws before rotation.","commonSituations":"OpenRouter changed its free-tier offering and the filter matches nothing; account in a region with no free models; transient empty response from /models; the free model ids changed naming and the loader's filter no longer matches.","solutions":["Pin a specific known-good free model via CAREER_OPS_MODEL to bypass the list entirely (e.g. google/gemini-2.0-flash-exp:free).","Re-run loadFreeModels (the empty list is often transient) or check https://openrouter.ai/models?max_price=0 for current free models.","Check your OpenRouter account standing — some account states lose free-tier access.","If the loader filter is the culprit, update the free-model detection in loadFreeModels."],"exampleFix":"# before — empty free list\nnode openrunner-runner.mjs ...\n# throws: No free OpenRouter models are available.\n\n# after — pin a known free model\nexport CAREER_OPS_MODEL=google/gemini-2.0-flash-exp:free","handlingStrategy":"fallback","validationCode":"const freeCount = await loadFreeModels().then(m => m.length).catch(() => -1);\nif (freeCount === 0) {\n  process.env.CAREER_OPS_MODEL = 'google/gemini-2.0-flash-exp:free';\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await callOpenRouter(systemPrompt, userMessage);\n} catch (e) {\n  if (e.message.startsWith('No free OpenRouter models are available')) {\n    process.env.CAREER_OPS_MODEL = 'google/gemini-2.0-flash-exp:free';\n    return await callOpenRouter(systemPrompt, userMessage);\n  }\n  throw e;\n}","preventionTips":["Keep a known-good free model id handy to pin via CAREER_OPS_MODEL when the list is empty.","Verify account standing and region support for free models on OpenRouter.","Check https://openrouter.ai/models?max_price=0 periodically for current free offerings.","Treat an empty list as transient first — retry before pinning."],"tags":["openrouter","configuration","startup","model-rotation"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}