agalwood/Motrix · error · HttpError

plugin.http.response_type_required

plugin.http.response_type_required

Error message

responseType is required (text | json | bytes)

What it means

request() deliberately does not default responseType. The caller must declare one of 'text' | 'json' | 'bytes' so the response body is parsed and typed unambiguously. Omitting it throws before any URL parsing or network work occurs.

Source

Thrown at src/core/plugin/capabilities/http.ts:242

  private readonly defaultTimeoutMs: number
  private readonly defaultMaxBodyBytes: number

  constructor(opts?: HttpCapabilityHostOptions) {
    this.cookieJar = opts?.cookieJar
    this.defaultTimeoutMs = opts?.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS
    this.defaultMaxBodyBytes =
      opts?.defaultMaxBodyBytes ?? DEFAULT_MAX_BODY_BYTES
  }

  // -------------------------------------------------------------------------
  // request
  // -------------------------------------------------------------------------

  async request<R extends HttpResponseType>(
    opts: HttpRequestOptions<R>
  ): Promise<HttpResponse<R>> {
    if (opts.responseType === undefined) {
      throw new HttpError(
        'plugin.http.response_type_required',
        'responseType is required (text | json | bytes)'
      )
    }

    const parsed = parseUrl(opts.url)
    checkScheme(parsed)

    const timeoutMs = clampTimeout(opts.timeoutMs, this.defaultTimeoutMs)
    const maxBodyBytes = clampMaxBody(
      opts.maxBodyBytes,
      this.defaultMaxBodyBytes
    )
    const method = (opts.method ?? 'GET').toUpperCase() as Dispatcher.HttpMethod
    const redirect = opts.redirect ?? 'follow'
    const useCookies = opts.cookies === 'jar'
    const dispatcher = pickDispatcher(opts.proxy)

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Always set opts.responseType to 'text', 'json', or 'bytes' on every request() call.
  2. If using http.get/http.post convenience helpers, confirm they forward responseType.
  3. Make the options object's type HttpRequestOptions<'json'> (or similar) so the compiler rejects omission.

Example fix

// before
await http.request({ url: 'https://api.example.com', method: 'GET' })

// after
await http.request({ url: 'https://api.example.com', method: 'GET', responseType: 'json' })
Defensive patterns

Strategy: type-guard

Validate before calling

const RESPONSE_TYPES = ['text', 'json', 'bytes'] as const
if (!RESPONSE_TYPES.includes(opts.responseType)) {
  throw new Error('responseType must be set')
}

Type guard

type ResponseType = 'text' | 'json' | 'bytes'
function hasResponseType<R extends ResponseType>(
  o: { responseType?: R }
): o is { responseType: R } {
  return o.responseType === 'text' || o.responseType === 'json' || o.responseType === 'bytes'
}

Prevention

When it happens

Trigger: Calling http.request({ url, method }) with no responseType; copy-pasting a fetch()-style call into this API assuming a default Response object; passing a partially-built options object whose responseType was conditionally set and ended up undefined.

Common situations: Migration from fetch/axios which return raw responses; TypeScript bypassed via `any`; refactor that hoisted options construction away from the call site.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/3213e4ea4a211490. Report an issue: GitHub.