hoppscotch/hoppscotch · error · Error

Fetch failed: ${errorMessage}

Error message

Fetch failed: ${errorMessage}

What it means

Top-level failure in hopp-fetch's fetch replacement: the kernelInterceptor.execute(relayRequest) returned an E.Left, so the request never produced a Response. The message is built by inspecting the left value — if it's a string it's used directly; if it's an object with a humanMessage.heading function, that's called; otherwise 'Unknown error'. This is the single chokepoint for every relay-backed fetch in the app.

Source

Thrown at packages/hoppscotch-common/src/helpers/hopp-fetch.ts:55

    // Execute via interceptor
    const execution = kernelInterceptor.execute(relayRequest)
    const result = await execution.response

    if (E.isLeft(result)) {
      const error = result.left

      const errorMessage =
        typeof error === "string"
          ? error
          : typeof error === "object" &&
              error !== null &&
              "humanMessage" in error
            ? typeof error.humanMessage.heading === "function"
              ? error.humanMessage.heading(() => "Unknown error")
              : "Unknown error"
            : "Unknown error"
      throw new Error(`Fetch failed: ${errorMessage}`)
    }

    // Convert RelayResponse to serializable Response-like object
    // Native Response objects can't cross VM boundaries
    return convertRelayResponseToSerializableResponse(result.right)
  }
}

/**
 * Converts Fetch API request to RelayRequest format
 */
async function convertFetchToRelayRequest(
  input: RequestInfo | URL,
  init?: RequestInit
): Promise<RelayRequest> {
  const urlStr =
    typeof input === "string"
      ? input

View on GitHub (pinned to 1acb8a3a75)

Solutions

  1. If using the agent interceptor, confirm the agent is running and authenticated (see error 78).
  2. Read the errorMessage portion of the thrown string to identify the underlying cause (network, agent, CORS).
  3. For CORS, route the request through the agent/proxy rather than the browser directly.
  4. If the left value is a structured error with humanMessage, surface error.humanMessage.body or .heading to the user instead of 'Unknown error'.

Example fix

// before
const errorMessage =
  typeof error === "string"
    ? error
    : typeof error === "object" && error !== null && "humanMessage" in error
      ? typeof error.humanMessage.heading === "function"
        ? error.humanMessage.heading(() => "Unknown error")
        : "Unknown error"
      : "Unknown error"
throw new Error(`Fetch failed: ${errorMessage}`)

// after
const errorMessage =
  typeof error === "string"
    ? error
    : typeof error === "object" && error !== null && "humanMessage" in error
      ? [error.humanMessage.heading?.(() => "Unknown error"), error.humanMessage.body?.()].filter(Boolean).join(" — ")
      : JSON.stringify(error)
throw new Error(`Fetch failed: ${errorMessage}`)
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight reachability check (best-effort) before the real fetch
const canReach = async (url: string): Promise<boolean> => {
  try {
    await fetch(url, { method: 'HEAD', mode: 'no-cors' })
    return true
  } catch { return false }
}

Type guard

const isStructuredFetchError = (e: unknown): e is { humanMessage: { heading: Function; body?: () => string } } =>
  typeof e === 'object' && e !== null && 'humanMessage' in e

Try / catch

try {
  return await hoppFetch(url, init)
} catch (e) {
  const m = e.message
  if (m.startsWith('Fetch failed:')) {
    const detail = m.slice('Fetch failed:'.length).trim()
    if (detail === 'Agent not running') await promptStartAgent()
    else toast.error(detail)
  }
  throw e
}

Prevention

When it happens

Trigger: Any relay request (REST, GraphQL, backend call) fails at the interceptor layer: DNS failure, connection refused, TLS error, the agent interceptor rejecting (see error 78), a network policy block, or an interceptor-thrown structured error whose humanMessage is invoked.

Common situations: The Hoppscotch agent is not running (the agent interceptor throws 'Agent not running' which surfaces here); a CORS preflight fails; the target host is unreachable from the runtime; a corporate proxy blocks the request; the request was cancelled and the interceptor returns Left('cancelled').

Related errors


AI-assisted analysis of hoppscotch/hoppscotch@1acb8a3a75 (2026-08-12). Data as JSON: /api/errors/5cf691203584aa03. Report an issue: GitHub.