{"record":{"id":"96b1071d403c6512","repo":"angular/angular","slug":"jsonp-wrong-response-type","errorCode":"JSONP_WRONG_RESPONSE_TYPE","errorMessage":"JSONP requests must use Json response type.","messagePattern":"JSONP requests must use Json response type\\.","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"packages/common/http/src/jsonp.ts","lineNumber":139,"sourceCode":"    return `ng_jsonp_callback_${nextRequestId++}`;\n  }\n\n  /**\n   * Processes a JSONP request and returns an event stream of the results.\n   * @param req The request object.\n   * @returns An observable of the response events.\n   *\n   */\n  handle(req: HttpRequest<never>): Observable<HttpEvent<any>> {\n    // Firstly, check both the method and response type. If either doesn't match\n    // then the request was improperly routed here and cannot be handled.\n    if (req.method !== 'JSONP') {\n      throw new RuntimeError(\n        RuntimeErrorCode.JSONP_WRONG_METHOD,\n        ngDevMode && JSONP_ERR_WRONG_METHOD,\n      );\n    } else if (req.responseType !== 'json') {\n      throw new RuntimeError(\n        RuntimeErrorCode.JSONP_WRONG_RESPONSE_TYPE,\n        ngDevMode && JSONP_ERR_WRONG_RESPONSE_TYPE,\n      );\n    }\n\n    // Check the request headers. JSONP doesn't support headers and\n    // cannot set any that were supplied.\n    if (req.headers.keys().length > 0) {\n      throw new RuntimeError(\n        RuntimeErrorCode.JSONP_HEADERS_NOT_SUPPORTED,\n        ngDevMode && JSONP_ERR_HEADERS_NOT_SUPPORTED,\n      );\n    }\n\n    if (!this.isAllowedJsonpUrl(req.urlWithParams)) {\n      throw new RuntimeError(RuntimeErrorCode.JSONP_UNSAFE_URL, ngDevMode && JSONP_ERR_UNSAFE_URL);\n    }\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/angular/angular/blob/51cb07e98081ab7e4e84a9e0949266a8e19cca84/packages/common/http/src/jsonp.ts#L121-L157","documentation":"Thrown by JsonpClientBackend.handle when a request with method 'JSONP' arrives with a responseType other than 'json'. A JSONP response is executed as a JavaScript script that passes a value to a callback, so 'text', 'arraybuffer', 'blob', or 'body' response types are physically impossible over JSONP. The check runs before any script tag is created, as a guard against improperly routed or hand-built requests.","triggerScenarios":"Hand-constructing an HttpRequest with method 'JSONP' and a non-json responseType (e.g. new HttpRequest('JSONP', url, {responseType: 'text'})) and letting the JsonpInterceptor route it to JsonpClientBackend; or cloning a JSONP request in an interceptor with a changed responseType.","commonSituations":"Copying a request-building helper that defaults responseType: 'text'; an interceptor that clones requests and overrides responseType; migrating a normal GET to JSONP while keeping its options object. Note JSONP itself is deprecated since Angular 22.1 due to XSS risk.","solutions":["Use responseType 'json' (the default) for any JSONP request, or just call HttpClient.jsonp(url, callback) which sets it correctly","If you need text/blob/arraybuffer bodies, use a normal http.get()/http.post() over XHR or fetch instead of JSONP","Audit interceptors that clone requests with responseType overrides and skip or fix them for method === 'JSONP'","Prefer migrating off JSONP entirely (it is deprecated) to standard CORS-enabled requests"],"exampleFix":"// before\nconst req = new HttpRequest('JSONP', 'https://api.example.com/data', null, {\n  responseType: 'text', // JSONP can only deliver JSON\n});\nhttp.request(req).subscribe();\n\n// after\nhttp.jsonp<unknown>('https://api.example.com/data', 'callback').subscribe();\n// or, for non-JSON payloads, a normal request:\nhttp.get('https://api.example.com/data', {responseType: 'text'});","handlingStrategy":"validation","validationCode":"function assertJsonpCompatible(req: HttpRequest<unknown>): void {\n  if (req.method === 'JSONP' && req.responseType !== 'json') {\n    throw new Error(`JSONP request to ${req.url} must use responseType 'json'`);\n  }\n}\n// run before handing the request to HttpClient / an interceptor chain","typeGuard":"type JsonpRequest = HttpRequest<never> & {method: 'JSONP'; responseType: 'json'};\nfunction isJsonpRequest(req: HttpRequest<unknown>): req is JsonpRequest {\n  return req.method === 'JSONP' && req.responseType === 'json';\n}","tryCatchPattern":"try {\n  http.jsonp<unknown>(url, 'cb').subscribe(next, done);\n} catch (err) {\n  // backend validation errors throw synchronously at the HttpClient call site\n  if (err instanceof Error && /JSONP/.test(err.message)) { /* fix request config */ }\n  else throw err;\n}","preventionTips":["Always use http.jsonp(url, callback) instead of hand-building 'JSONP' requests — it sets method and responseType correctly","In interceptors, never change responseType on requests whose method is 'JSONP'","Reserve JSONP for JSON-only legacy endpoints; use http.get() for everything else"],"tags":["http","jsonp","response-type","request-configuration"],"backgroundTag":"invalid-request-options","analyzedSha":"51cb07e98081ab7e4e84a9e0949266a8e19cca84","analyzedAt":"2026-08-22T07:04:54.531Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}