{"record":{"id":"824d6240ac90a737","repo":"prometheus/prometheus","slug":"missing-error-field-in-response-json-824d62","errorCode":null,"errorMessage":"missing \"error\" field in response JSON","messagePattern":"missing \"error\" field in response JSON","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/ui/module/codemirror-promql/src/client/prometheus.ts","lineNumber":233,"sourceCode":"    this.abortControllers.add(controller);\n\n    if (init) {\n      init.headers = this.requestHeaders;\n      init.signal = controller.signal;\n    } else {\n      init = { headers: this.requestHeaders, signal: controller.signal };\n    }\n    return this.fetchFn(this.url + resource, init)\n      .then((res) => {\n        if (!res.ok && ![badRequest, unprocessableEntity, serviceUnavailable].includes(res.status)) {\n          throw new Error(res.statusText);\n        }\n        return res;\n      })\n      .then((res) => res.json())\n      .then((apiRes: APIResponse<T>) => {\n        if (apiRes.status === 'error') {\n          throw new Error(apiRes.error !== undefined ? apiRes.error : 'missing \"error\" field in response JSON');\n        }\n        if (apiRes.data === undefined) {\n          throw new Error('missing \"data\" field in response JSON');\n        }\n        return apiRes.data;\n      })\n      .finally(() => {\n        this.abortControllers.delete(controller);\n      });\n  }\n\n  private buildRequest(endpoint: string, params: URLSearchParams) {\n    let uri = endpoint;\n    let body: URLSearchParams | null = params;\n    if (this.httpMethod === 'GET') {\n      uri = `${uri}?${params}`;\n      body = null;\n    }","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/prometheus/prometheus/blob/44d6a0e0b1dbdcba4e68853d50e0bafc87d90507/web/ui/module/codemirror-promql/src/client/prometheus.ts#L215-L251","documentation":"The codemirror-promql client parsed a JSON body with status:'error' but no 'error' field, violating the Prometheus API response contract. Autocomplete and metadata lookups fail with this placeholder message rather than undefined behavior.","triggerScenarios":"A response like {\"status\":\"error\"} from /api/v1/series, /api/v1/labels, or metadata endpoints used by the editor — usually a rewritten or malformed body from an intermediary.","commonSituations":"API gateway rewriting error bodies; test mocks missing the error field; a non-Prometheus backend accidentally targeted by the editor client.","solutions":["Inspect the raw response body for the failing editor request.","Point the codemirror-promql client at a real Prometheus endpoint.","Fix proxies/mocks to preserve the full error envelope.","Update mocks in tests to include both status and error fields."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const r = await fetch(url);\nconst body = await r.json();\nif (body?.status === 'error' && body.error === undefined) {\n  // malformed envelope: log and use a generic message yourself\n}","typeGuard":"function hasErrorField(r: unknown): r is { status: 'error'; error: string } {\n  return typeof (r as any)?.error === 'string';\n}","tryCatchPattern":"catch (err) {\n  if (err instanceof Error && err.message.includes('missing \"error\" field')) {\n    // contract violation from intermediary: inspect raw body\n  }\n}","preventionTips":["Never strip or reshape API JSON bodies in proxies.","Mock full Prometheus response envelopes in editor tests.","Validate response shape in dev with a schema check before wiring autocomplete."],"tags":["codemirror","json","contract","promql-editor"],"backgroundTag":null,"analyzedSha":"44d6a0e0b1dbdcba4e68853d50e0bafc87d90507","analyzedAt":"2026-08-15T08:44:33.427Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}