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
- Add `provider` (or `model`) as a non-empty string to the JSON body of the request.
- Verify the field is sent in the JSON body, not as a URL query parameter or header.
- Check the client is not posting an empty body / wrong Content-Type causing fields to be dropped.
- 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
- Validate request bodies with a schema (zod/ajv) before hitting the endpoint.
- Standardize on `model` across your clients since the API accepts it as an alias.
- Always send Content-Type: application/json so body parsing succeeds.
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
- Missing required field: query
- Unknown provider: ${providerInput}
- Provider ${providerId} does not support web search
- Xquik queryType must be Latest or Top
- Bing TTS returned empty audio
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/9e12cce0a8aae0e9.
Report an issue: GitHub.