{"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":280,"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":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/openrouter-runner.mjs#L262-L298","documentation":"Thrown by callOpenRouter() after loadFreeModels() returns an empty array — meaning the model list loaded 'successfully' but contains nothing, so there is no model to call. Distinct from error 92 (which fires inside loadFreeModels when filtering finds nothing): this fires when an empty list reached the caller anyway, e.g. a cached empty list or a future path where loadFreeModels returns [] without throwing.","triggerScenarios":"`await loadFreeModels()` resolves to [] — a previously cached empty result, or a code path where the fetch failure was swallowed and [] returned; callOpenRouter then aborts before building the rotation list.","commonSituations":"Session-level cache holding an empty list from a failed first load; test/mocked environment returning []; OpenRouter genuinely listing no free models for the account at load time.","solutions":["Clear the module-level cache (restart the process) so loadFreeModels refetches from the API.","Run a standalone fetch of the models endpoint to check whether free models actually exist right now.","Check the earlier `[models] Failed to fetch...` log lines — an earlier failure may have poisoned the cache.","If no free models exist for the account/plan, configure paid models and ensure the key has credits.","Harden loadFreeModels so it never caches an empty list as a success value."],"exampleFix":"// before\nconst freeModels = ...;\nif (freeModels !== null) return freeModels;\n// after (don't cache empty as success)\nconst freeModels = ...;\nif (freeModels !== null && freeModels.length > 0) return freeModels;","handlingStrategy":"validation","validationCode":"const models = await loadFreeModels();\nif (!Array.isArray(models) || models.length === 0) {\n  throw new Error('No free models available — restart to clear the cache or add credits/paid models.');\n}","typeGuard":"function hasUsableModels(models) {\n  return Array.isArray(models) && models.some(m => typeof m === 'string' && m.length > 0);\n}","tryCatchPattern":"try {\n  result = await callOpenRouter(systemPrompt, userMessage);\n} catch (err) {\n  if (err.message.startsWith('No free OpenRouter models')) {\n    console.error('Model list empty: restart the process to force a refetch, or switch to paid models.');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Never cache an empty model list as a success value.","Refresh the model list at the start of each session rather than trusting session cache.","Alert when loadFreeModels() returns fewer than a threshold (e.g. 3) of free models.","Maintain a configured paid-model fallback for accounts without free models."],"tags":["openrouter","model-rotation","empty-result","caching"],"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"}