decolua/9router · error

qoder: model_config for "${qoderKey}" not yet known (run a m

Error message

qoder: model_config for "${qoderKey}" not yet known (run a model list fetch or check upstream connectivity)

What it means

Qoder's executor builds request bodies from model metadata (is_reasoning, max_output_tokens, model key) fetched dynamically from Qoder's model-list API and cached per credential. buildQoderRequestBody() looks up the requested model key; if the cache misses it forces one refresh, and if the key is still absent it throws this error because it cannot construct a valid upstream request for an unknown model.

Source

Thrown at open-sse/executors/qoder.js:142

  return s && s.length > n ? `${s.slice(0, n)}...` : s || "";
}

/**
 * Map the OpenAI-style request body into the exact shape Qoder expects.
 */
async function buildQoderRequestBody({ model, body, credentials, log, proxyOptions, signal }) {
  const qoderKey = String(model || "").replace(/^qoder\//, "");
  
  // Fetch model config from dynamic API instead of relying on static QODER_MODEL_MAP.
  // This allows support for new Qoder models (e.g., qmodel_latest) without code changes.
  let modelConfig = await getQoderModelConfig(credentials, qoderKey, { log, proxyOptions, signal });
  if (!modelConfig) {
    // Try a forced refresh once before giving up — the cache may simply
    // not be populated yet on first ever call for this credential.
    const refreshed = await resolveQoderModels(credentials, { forceRefresh: true, log, proxyOptions, signal });
    const retried = refreshed?.rawConfigs.get(qoderKey);
    if (!retried) {
      throw new Error(
        `qoder: model_config for "${qoderKey}" not yet known (run a model list fetch or check upstream connectivity)`,
      );
    }
    modelConfig = { ...retried, key: qoderKey };
  }

  const { messages, systemText } = normalizeMessages(body.messages || []);
  const tools = body.tools;
  const isReasoning = !!modelConfig.is_reasoning;
  const maxOutputTokens = Number(modelConfig.max_output_tokens) || 0;

  let maxTokens = 32_768;
  if (maxOutputTokens > 0) maxTokens = maxOutputTokens;
  if (typeof body.max_tokens === "number" && body.max_tokens > 0 && body.max_tokens < maxTokens) {
    maxTokens = body.max_tokens;
  }
  if (typeof body.max_completion_tokens === "number" && body.max_completion_tokens > 0 && body.max_completion_tokens < maxTokens) {
    maxTokens = body.max_completion_tokens;

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Run a model list fetch (GET the router's /v1/models for qoder) to see the valid model keys and correct the client's model name
  2. Verify upstream connectivity for the credential — the error explicitly suggests checking connectivity; test the Qoder model-list endpoint with the credential
  3. Update 9router in case the model was added upstream and needs a newer alias map in config/providerModels.js or the resolver
  4. Re-authenticate the Qoder credential if the model-list call fails with auth errors
  5. Retry once connectivity is restored — the forced refresh will then populate the cache

Example fix

// before
model: 'qoder/qmodel_latest_v3' // guessed name
// after
model: 'qoder/qmodel-latest'   // exact key from GET /v1/models
Defensive patterns

Strategy: validation

Validate before calling

const models = await fetch('/v1/models').then(r => r.json());
const valid = models.data.some(m => m.id === 'qoder/qmodel-latest');
if (!valid) throw new Error('pick a model id from GET /v1/models');

Try / catch

try {
  await executor.execute(req);
} catch (e) {
  if (String(e.message).includes('not yet known')) {
    // refresh qoder model list, then retry with a valid key
    await refreshQoderModels();
    return retryWithCorrectedModel(req);
  }
  throw e;
}

Prevention

When it happens

Trigger: A request targets a Qoder model whose key is not present in the freshly fetched model list: typo'd/renamed model id (e.g. qmodel_latest vs qmodel-latest), a brand-new upstream model the deployed resolver can't map, upstream connectivity failure during both cached and forced refresh, or an expired/invalid credential making the model-list call fail silently.

Common situations: Client (e.g. Claude Code/Cursor) configured with a model alias that no longer exists upstream; first-ever call before any model fetch succeeded plus a network outage; Qoder retiring or renaming models; a proxy blocking the model-list endpoint.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/55b0b4e8654c13c1. Report an issue: GitHub.