decolua/9router · warning

Missing required field: provider (or model)

Error message

Missing required field: provider (or model)

What it means

handleSearch validates the request body before dispatching a web-search request. The body must contain either `provider` or `model` (they are synonyms; provider IS the model for web search). If neither is a non-empty string, the handler returns HTTP 400 'Missing required field: provider (or model)'. This is an input-validation guard, not a runtime failure.

Source

Thrown at src/sse/handlers/search.js:62

    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 (!providerInput || typeof providerInput !== "string") {
    log.warn("SEARCH", "Missing provider/model");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: provider (or model)");
  }

  if (!query || typeof query !== "string" || !query.trim()) {
    log.warn("SEARCH", "Missing query");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: query");
  }

  // Combo expansion: providerInput may be a combo name → run fallback/round-robin across providers
  const combos = await getCombos();
  const comboModels = getComboModelsFromData(providerInput, combos);
  if (comboModels) {
    const comboStrategies = settings.comboStrategies || {};
    const comboStrategy = comboStrategies[providerInput]?.fallbackStrategy || settings.comboStrategy || "fallback";
    const comboStickyLimit = settings.comboStickyRoundRobinLimit;
    log.info("SEARCH", `Combo "${providerInput}" with ${comboModels.length} providers (strategy: ${comboStrategy}, sticky: ${comboStickyLimit})`);
    return handleComboChat({
      body,

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Add `provider` (or `model`) as a non-empty string to the JSON body of the request.
  2. Verify the field is sent in the JSON body, not as a URL query parameter or header.
  3. Check the client is not posting an empty body / wrong Content-Type causing fields to be dropped.
  4. If proxying, ensure upstream middleware does not strip or rename the provider/model field.

Example fix

// before
await fetch('/v1/search', { method: 'POST', body: JSON.stringify({ query: 'rust async' }) });
// after
await fetch('/v1/search', { method: 'POST', body: JSON.stringify({ provider: 'tavily', query: 'rust async' }) });
Defensive patterns

Strategy: validation

Validate before calling

const provider = body.provider || body.model;
if (typeof provider !== 'string' || !provider) {
  throw new TypeError('provider (or model) is required and must be a non-empty string');
}

Type guard

function hasProvider(b) { return typeof b === 'object' && b !== null && typeof (b.provider ?? b.model) === 'string' && (b.provider ?? b.model).length > 0; }

Prevention

When it happens

Trigger: POST /v1/search (or the search endpoint mapped to handleSearch) with a JSON body lacking both `provider` and `model`, containing them as non-string values (e.g. null, number, object), or as an empty string. Also happens when a client serializes the provider under a wrong key name.

Common situations: Hand-written curl scripts omitting the field; SDK clients built for the chat endpoint (which uses `model` inside a nested payload) posting the wrong shape; a UI bug sending `model: null` after clearing a selection; middleware that strips fields; sending provider as a query param instead of in the JSON body.

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/9e12cce0a8aae0e9. Report an issue: GitHub.