decolua/9router · warning
Missing required field: query
Error message
Missing required field: query
What it means
After the provider/model check, handleSearch requires a non-empty, non-whitespace `query` string. This error means the search body was well-formed enough to name a provider but carried no usable search text. It is a 400 BAD_REQUEST returned synchronously before any provider or credential lookup.
Source
Thrown at src/sse/handlers/search.js:67
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,
models: comboModels,
handleSingleModel: (b, m) => handleSingleProviderSearch(b, m, request, apiKey, settings),
log,
comboName: providerInput,
comboStrategy,View on GitHub (pinned to 90b52e06ff)
Solutions
- Include a non-empty trimmed `query` string in the request body.
- Add client-side validation: reject empty/whitespace-only query before sending.
- Confirm the client targets the search endpoint shape ({provider, query}) not the chat shape ({model, messages}).
- If building the body dynamically, log it before fetch to catch undefined interpolations.
Example fix
// before
const body = { provider: 'brave', query: userInput }; // userInput may be ''
// after
if (!userInput?.trim()) throw new Error('query required');
const body = { provider: 'brave', query: userInput.trim() }; Defensive patterns
Strategy: validation
Validate before calling
if (typeof body.query !== 'string' || !body.query.trim()) {
throw new TypeError('query is required and must be a non-whitespace string');
} Type guard
function hasQuery(b) { return typeof b?.query === 'string' && b.query.trim().length > 0; } Prevention
- Trim and check query length in UI before enabling submit.
- Share one request schema between chat and search clients to avoid shape confusion.
- Log outgoing bodies in dev to catch undefined interpolations.
When it happens
Trigger: POST to the search endpoint with body.query missing, non-string (null/number/object), an empty string, or a whitespace-only string like ' '. Provider is present and valid, so validation fails only at the query step.
Common situations: A UI sending the request before the user typed a query; form submit handlers firing on empty input; clients reusing a chat-completion body (messages array) against the search endpoint; template literals interpolating an undefined variable into query.
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: provider (or model)
- Missing Zed callback URL
- Unknown provider: ${providerInput}
- Provider ${providerId} does not support web search
- Xquik queryType must be Latest or Top
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/82fde62fdc3acbc1.
Report an issue: GitHub.