decolua/9router · error

Missing required field: provider (or model)

Error message

Missing required field: provider (or model)

What it means

HTTP 400 returned by handleFetch when neither `provider` nor `model` is present (or not a string) in the JSON body. The fetch endpoint routes by provider id (which doubles as the model for webFetch), accepting either field name, but requires one of them.

Source

Thrown at src/sse/handlers/fetch.js:65

    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("FETCH", "Missing provider/model");
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: provider (or model)");
  }

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

  // Validate URL format
  try {
    new URL(targetUrl);
  } catch {
    log.warn("FETCH", "Invalid URL", { url: targetUrl });
    return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid URL format");
  }

  // SSRF guard: reject internal/private/metadata targets
  try {

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Add `provider` (or `model`) as a string in the body, e.g. "jina" or the provider id from the dashboard
  2. Validate the payload shape client-side before sending
  3. Check field spelling — only `provider` and `model` are accepted

Example fix

// before
{ url: 'https://example.com' }
// after
{ provider: 'jina', url: 'https://example.com' }
Defensive patterns

Strategy: validation

Validate before calling

function assertFetchPayload(body) {
  const p = body?.provider ?? body?.model;
  if (typeof p !== 'string' || !p.trim()) throw new Error('fetch payload requires string `provider` (or `model`)');
  if (typeof body?.url !== 'string') throw new Error('fetch payload requires string `url`');
}

Type guard

function hasProvider(body) {
  const p = body?.provider ?? body?.model;
  return typeof p === 'string' && p.trim().length > 0;
}

Try / catch

const res = await post('/v1/fetch', payload);
if (res.status === 400 && (await res.text()).includes('provider (or model)')) {
  console.error('Add `provider` or `model` to the fetch payload');
}

Prevention

When it happens

Trigger: POST to the fetch endpoint with a body like {"url":"https://example.com"} or {"provider":123}, or with the provider under a misspelled key ("provide", "service").

Common situations: Copied a curl example and dropped a field; SDK builds body from options where the provider option name differs; passing a non-string (object/null) provider value.

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/264e789435edc7e4. Report an issue: GitHub.