{"record":{"id":"3213e4ea4a211490","repo":"agalwood/Motrix","slug":"plugin-http-response-type-required","errorCode":"plugin.http.response_type_required","errorMessage":"responseType is required (text | json | bytes)","messagePattern":"responseType is required \\(text \\| json \\| bytes\\)","errorType":"validation","errorClass":"HttpError","httpStatus":null,"severity":"error","filePath":"src/core/plugin/capabilities/http.ts","lineNumber":242,"sourceCode":"  private readonly defaultTimeoutMs: number\n  private readonly defaultMaxBodyBytes: number\n\n  constructor(opts?: HttpCapabilityHostOptions) {\n    this.cookieJar = opts?.cookieJar\n    this.defaultTimeoutMs = opts?.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS\n    this.defaultMaxBodyBytes =\n      opts?.defaultMaxBodyBytes ?? DEFAULT_MAX_BODY_BYTES\n  }\n\n  // -------------------------------------------------------------------------\n  // request\n  // -------------------------------------------------------------------------\n\n  async request<R extends HttpResponseType>(\n    opts: HttpRequestOptions<R>\n  ): Promise<HttpResponse<R>> {\n    if (opts.responseType === undefined) {\n      throw new HttpError(\n        'plugin.http.response_type_required',\n        'responseType is required (text | json | bytes)'\n      )\n    }\n\n    const parsed = parseUrl(opts.url)\n    checkScheme(parsed)\n\n    const timeoutMs = clampTimeout(opts.timeoutMs, this.defaultTimeoutMs)\n    const maxBodyBytes = clampMaxBody(\n      opts.maxBodyBytes,\n      this.defaultMaxBodyBytes\n    )\n    const method = (opts.method ?? 'GET').toUpperCase() as Dispatcher.HttpMethod\n    const redirect = opts.redirect ?? 'follow'\n    const useCookies = opts.cookies === 'jar'\n    const dispatcher = pickDispatcher(opts.proxy)\n","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/plugin/capabilities/http.ts#L224-L260","documentation":"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.","triggerScenarios":"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.","commonSituations":"Migration from fetch/axios which return raw responses; TypeScript bypassed via `any`; refactor that hoisted options construction away from the call site.","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."],"exampleFix":"// before\nawait http.request({ url: 'https://api.example.com', method: 'GET' })\n\n// after\nawait http.request({ url: 'https://api.example.com', method: 'GET', responseType: 'json' })","handlingStrategy":"type-guard","validationCode":"const RESPONSE_TYPES = ['text', 'json', 'bytes'] as const\nif (!RESPONSE_TYPES.includes(opts.responseType)) {\n  throw new Error('responseType must be set')\n}","typeGuard":"type ResponseType = 'text' | 'json' | 'bytes'\nfunction hasResponseType<R extends ResponseType>(\n  o: { responseType?: R }\n): o is { responseType: R } {\n  return o.responseType === 'text' || o.responseType === 'json' || o.responseType === 'bytes'\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["http","api-usage","typescript","validation"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}