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
- Always set opts.responseType to 'text', 'json', or 'bytes' on every request() call.
- If using http.get/http.post convenience helpers, confirm they forward responseType.
- 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
- Type the options object as HttpRequestOptions<'json'> (or 'text'/'bytes') so the compiler rejects omission.
- Never spread a partial options bag into request() without asserting responseType.
- Add an eslint rule or unit test that every request() call in the plugin sets responseType.
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
- IpcInvalidPayload
- taskId must be a string
- Key must be 16 bytes, got ${key.length}
- IV must be 16 bytes, got ${iv.length}
- plugin.http.invalid_url
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/3213e4ea4a211490.
Report an issue: GitHub.