Skip to content

Web Tools Error Codes

This document defines the structured error codes for built-in web tools (web_search / fetch_content / get_search_content). For tool API, see web-tools.md; for provider behavior, see web-providers.md; for configuration, see configuration.md.

Canonical source:

  • Complete error code list: WEB_ERROR_CODES in src/modules/web/errors.ts.
  • Actual return structure: WebToolError in src/modules/web/types.ts.
  • Specific return paths: src/modules/web/search.ts, src/modules/web/fetch.ts, src/modules/web/storage.ts, src/modules/web/providers/select-provider.ts.
  • If README / README.zh conflicts with this document, this document and source code take precedence. README only retains common error descriptions, not as a complete error code list.

Error return structure:

json
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message"
  }
}

message is an actionable hint for the caller, may be optimized across versions; automation logic should prefer code.

Status definitions

StatusMeaning
activeCurrently has a direct return path
reservedDefined in WEB_ERROR_CODES but currently has no direct return path; reserved for future stable refinement
deprecatedOld name or historical documentation name, no longer returned as canonical code

Current canonical error code list

The table below covers all error codes currently defined in WEB_ERROR_CODES.

Error codeStatusMeaningTypical causeReturned byRetryableRelated source
INVALID_INPUTactiveGeneral input or provider configuration invalidMissing url/responseId; unsupported provider; explicit provider not enabled or missing endpointfetch_content, get_search_content, provider selectionNofetch.ts, storage.ts, providers/select-provider.ts
NOT_FOUNDactiveStored result or selector not foundresponseId does not exist; urlIndex/queryIndex out of bounds; specified url/query does not existget_search_contentNostorage.ts
WEB_SEARCH_FAILEDactiveSearch failure fallback errorProvider threw uncategorized error; provider response parse failure; auto mode had no successful providerweb_search, provider selectionDepends; source recovery suggestion is fallbackerrors.ts, search.ts, providers/select-provider.ts
WEB_SEARCH_TIMEOUTactiveSearch timed out or abortedProvider request timed out; call aborted by AbortSignalweb_searchYeserrors.ts, search.ts, abort.ts
WEB_SEARCH_NO_RESULTSreservedReserved: search returned no resultsIn current design "no results" is a success response: results = [], not an errorNot directly returnedNoerrors.ts, providers
WEB_SEARCH_INVALID_QUERYactiveQuery empty or no valid contentquery missing, or query/queries empty after trimweb_searchNosearch.ts
CONTENT_FETCH_FAILEDactiveContent fetch/extraction failure fallback errorURL security policy rejection; HTTP non-2xx; unsupported content type; binary content; redirect anomaly; Jina request anomaly; queue full; other uncategorized fetch errorsfetch_contentUsually no; depends on messagefetch.ts, security.ts, handlers.ts, concurrency.ts
CONTENT_FETCH_TIMEOUTactiveContent fetch timed out or abortedMain fetch request or Jina request timed out/abortedfetch_contentYeserrors.ts, fetch.ts, abort.ts
CONTENT_FETCH_INVALID_URLactiveURL format or protocol invalidURL cannot be parsed by new URL(); protocol is not HTTP/HTTPSfetch_contentNofetch.ts, security.ts
CONTENT_FETCH_TOO_LARGEreservedReserved: response body too largeCurrent implementation uses maxResponseBytes / maxContentChars truncation, does not treat truncation as errorNot directly returnedNoerrors.ts, fetch.ts
PROVIDER_RATE_LIMITEDactiveProvider rate limitedProvider returned HTTP 429web_searchYeserrors.ts, search.ts, providers
PROVIDER_UNAVAILABLEactiveProvider temporarily unavailableProvider returned HTTP 5xxweb_searchYeserrors.ts, search.ts, providers
PROVIDER_AUTH_FAILEDactiveProvider authentication failedAPI key missing or invalid; HTTP 401/403web_searchNoerrors.ts, search.ts, providers
NETWORK_ERRORactiveSearch provider network connection errorfetch failed, DNS ENOTFOUND, ECONN*, etc.web_searchYeserrors.ts, search.ts
PARSE_ERRORreservedReserved: parse failureCurrent provider JSON parse/response shape anomaly usually classified as WEB_SEARCH_FAILED; content handler parse failure usually falls back with parseWarningNot directly returnedNoerrors.ts, providers, handlers.ts
CACHE_ERRORreservedReserved: cache operation failureCurrent search cache is best-effort; local cache/storage over-limit handled via eviction or truncationNot directly returnedNoerrors.ts, cache.ts, storage.ts

Conclusions for six reserved/boundary error codes

Error codeCurrent conclusionDirectly returnedDescription
WEB_SEARCH_NO_RESULTSRetained as reservedNoCurrent semantics stable as success empty result; should not change results = [] to error.
WEB_SEARCH_INVALID_QUERYRetained and enabledYesEmpty query is a stable, testable input error, directly returns this code.
CONTENT_FETCH_INVALID_URLRetained and enabledYesURL parse failure and non-HTTP/HTTPS protocol can be stably distinguished, directly returns this code.
CONTENT_FETCH_TOO_LARGERetained as reservedNoCurrent implementation truncates read/output; does not treat "too large but truncated" as failure.
PARSE_ERRORRetained as reservedNoCurrent parse failures are mostly fallback or provider catch-all errors; no cross-provider parse layer introduced yet.
CACHE_ERRORRetained as reservedNoCurrent cache/storage does not expose as user-perceivable failure path.

Scenario-based explanations

web_search input and no results

  • Empty query or no valid query after trim: returns WEB_SEARCH_INVALID_QUERY.
  • Provider returns empty results: tool returns success, result is results = [], does not return WEB_SEARCH_NO_RESULTS.
  • WEB_SEARCH_NO_RESULTS only serves as a reserved code for possible future changes to no-result semantics.

Provider configuration, authentication, and request failures

  • Explicit unsupported, not enabled, or endpoint config invalid: INVALID_INPUT.
  • API key missing, HTTP 401/403: PROVIDER_AUTH_FAILED.
  • HTTP 429: PROVIDER_RATE_LIMITED.
  • HTTP 5xx: PROVIDER_UNAVAILABLE.
  • Network connection error: NETWORK_ERROR.
  • Provider JSON parse or response shape anomaly: currently continues to be classified as WEB_SEARCH_FAILED, not directly returning PARSE_ERROR. For current users, such exceptions and regular provider failures have essentially the same handling action; if structured parser, convert_content, or strong schema validation becomes complex in the future, PARSE_ERROR will be enabled.

fetch_content URL and security policy

  • Missing url/urls: INVALID_INPUT.
  • URL format invalid or protocol not HTTP/HTTPS: CONTENT_FETCH_INVALID_URL.
  • fetch_content's URL validation/security boundaries may reject localhost, private addresses, private hostnames, DNS resolution to private addresses, non-allowed protocols, etc.
  • Localhost/private IP, private hostname, DNS resolution to private addresses, etc. security policy rejections: continue to be classified as CONTENT_FETCH_FAILED. These failures are not "URL format invalid" but security boundary rejection; currently no new independent error code is added. If callers need to distinguish regular fetch failures from security policy rejections in the future, a code like CONTENT_FETCH_BLOCKED_BY_SECURITY_POLICY or CONTENT_FETCH_BLOCKED may be considered.

fetch_content content type and size limits

  • PDF, Office, ZIP, images, audio/video, executables, magic bytes detecting binary content: currently classified as CONTENT_FETCH_FAILED. For document-like formats such as PDF and Office, the error message may suggest convert_content as a follow-up action.
  • maxResponseBytes and maxContentChars currently used for truncating read/output; truncation results indicated by truncated: true, not returning CONTENT_FETCH_TOO_LARGE.
  • Currently maintains "truncation success" semantics: fetch_content is for agent reading; truncated content is usually more useful than direct failure.
  • If strict/full mode or allowTruncate=false is added in the future, reserved code CONTENT_FETCH_TOO_LARGE may be enabled.

Extraction / handler failure

  • Content handler parse failures prefer falling back to plain text, setting parseWarning.
  • Uncategorized exceptions are summarized by fetch_content as CONTENT_FETCH_FAILED.
  • Currently does not directly return PARSE_ERROR, avoiding converting recoverable parse fallbacks into user-visible errors.

Cache / storage

  • get_search_content miss: NOT_FOUND.
  • Search cache is currently best-effort; disabling cache is normal configuration, not an error.
  • Storage over-limit handled via eviction or truncation, not returning CACHE_ERROR or STORAGE_FULL.

Concurrency / connection pool

  • Queue full currently continues to be classified as CONTENT_FETCH_FAILED or WEB_SEARCH_FAILED, no new QUEUE_FULL / CONCURRENCY_LIMITED.
  • Connection pool / fetch bottom-layer exceptions will be classified by call path into CONTENT_FETCH_FAILED, WEB_SEARCH_FAILED, or NETWORK_ERROR.

Jina fallback

  • Jina fallback is fetch_content's internal recovery mechanism, not a user-selectable independent provider.
  • Jina returns non-2xx or empty content: falls back to original HTML result, does not return error.
  • Jina timeout/abort: may return CONTENT_FETCH_TIMEOUT.
  • Jina other request exceptions: may be classified as CONTENT_FETCH_FAILED.
  • Currently no new JINA_* error codes; if Jina becomes user-selectable/observable provider in the future, refinement may be considered.

HTTP status code mapping

Current mapHttpStatusToError() is used for search provider error classification:

StatusMaps toRetryable
401PROVIDER_AUTH_FAILEDNo
403PROVIDER_AUTH_FAILEDNo
429PROVIDER_RATE_LIMITEDYes
500PROVIDER_UNAVAILABLEYes
502PROVIDER_UNAVAILABLEYes
503PROVIDER_UNAVAILABLEYes
504PROVIDER_UNAVAILABLEYes
OtherWEB_SEARCH_FAILEDDepends on specific recovery

Recovery action descriptions

src/modules/web/errors.ts defines recovery suggestions for some error codes:

ActionMeaning
retryRetry the current request later
fallbackTry another provider or Jina fallback
skipSkip current content
abortConfiguration or input error, usually should not auto-retry

Not all actual returned WebToolError carry a recovery field; current tool return structure only guarantees error.code and error.message.

Phase 6 web/convert integration deliberately keeps follow-up guidance message-based. fetch_content may mention convert_content in error.message for likely document formats, but it does not expose public suggestion, nextAction, or suggestedTool fields. Add such fields only if multiple modules need a shared structured suggestion schema.

Deprecated / not canonical names

The following names are not current canonical codes and should not be written in README or user documentation as implemented dedicated codes:

  • FETCH_CONTENT_FAILED: deprecated old name; current canonical code is CONTENT_FETCH_FAILED.
  • CONTENT_TOO_LARGE: deprecated/old documentation name; current canonical reserved code is CONTENT_FETCH_TOO_LARGE.
  • STORAGE_FULL: not implemented; current storage uses entry limit eviction and content truncation.
  • CACHE_DISABLED: not implemented; disabling cache is normal configuration.
  • JINA_TIMEOUT / JINA_FAILED: not implemented; currently no independent Jina error codes.
  • QUEUE_FULL / CONCURRENCY_LIMITED: not implemented; queue full not exposed as independent web error code.

Future hardening

  • For stronger type constraints, WebToolError.error.code is already alignable with WebErrorCode; external JSON structure still maintains string compatibility.
  • If future providers uniformly throw identifiable parse/shape errors, or structured parser / convert_content / strong schema validation becomes complex, such errors may be refined from WEB_SEARCH_FAILED to PARSE_ERROR.
  • If fetch_content adds strict/full mode or allowTruncate=false in the future, CONTENT_FETCH_TOO_LARGE may be enabled.
  • If callers need to distinguish regular fetch failures from security policy rejections in the future, a code like CONTENT_FETCH_BLOCKED_BY_SECURITY_POLICY or CONTENT_FETCH_BLOCKED may be added.
  • If cache/storage failures become user-perceivable errors in the future, CACHE_ERROR may be enabled.