decolua/9router · error

Missing model

Error message

Missing model

What it means

HTTP 400 returned by handleEmbeddings when the request JSON body lacks a `model` field (or it is empty/falsy). The model string determines which provider routes the embedding request, so the handler fails fast before any credential lookup.

Source

Thrown at src/sse/handlers/embeddings.js:69

    log.debug("AUTH", "No API key provided (local mode)");
  }

  // Enforce API key if enabled in settings
  const settings = await getSettings();
  if (settings.requireApiKey) {
    if (!apiKey) {
      log.warn("AUTH", "Missing API key (requireApiKey=true)");
      return errorResponse(HTTP_STATUS.UNAUTHORIZED, "Missing API key");
    }
    const valid = await isValidApiKey(apiKey);
    if (!valid) {
      log.warn("AUTH", "Invalid API key (requireApiKey=true)");
      return errorResponse(HTTP_STATUS.UNAUTHORIZED, "Invalid API key");
    }
  }

  if (!modelStr) {
    log.warn("EMBEDDINGS", "Missing model");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing model");
  }

  if (!body.input) {
    log.warn("EMBEDDINGS", "Missing input");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: input");
  }

  const modelInfo = await getModelInfo(modelStr);
  if (!modelInfo.provider) {
    log.warn("EMBEDDINGS", "Invalid model format", { model: modelStr });
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid model format");
  }

  const { provider, model } = modelInfo;

  if (modelStr !== `${provider}/${model}`) {
    log.info("ROUTING", `${modelStr} → ${provider}/${model}`);

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Add `model` to the JSON body in `provider/model` form (e.g. "openai/text-embedding-3-small")
  2. Confirm the client SDK is configured with an embedding model name
  3. Print the request body before sending to confirm the field is populated

Example fix

// before
await fetch(url, { method: 'POST', body: JSON.stringify({ input: ['hello'] }) });
// after
await fetch(url, { method: 'POST', body: JSON.stringify({ model: 'openai/text-embedding-3-small', input: ['hello'] }) });
Defensive patterns

Strategy: validation

Validate before calling

function assertEmbeddingPayload(body) {
  if (!body || typeof body.model !== 'string' || !body.model.trim()) {
    throw new Error('embeddings payload requires a non-empty "model"');
  }
}

Type guard

function hasModel(body) {
  return typeof body === 'object' && body !== null &&
    typeof body.model === 'string' && body.model.trim().length > 0;
}

Try / catch

const res = await post('/v1/embeddings', payload);
if (res.status === 400 && (await res.text()).includes('Missing model')) {
  throw new Error('Payload missing `model` — set e.g. "openai/text-embedding-3-small"');
}

Prevention

When it happens

Trigger: POST to the embeddings endpoint with a JSON body like {"input":"hello"} or {"model":"","input":"x"}.

Common situations: Client code migrated from an SDK that puts the model in the URL instead of the body; building the payload dynamically and forgetting the model; testing with curl and omitting the field.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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