{"record":{"id":"eca5fd3174113ed5","repo":"thanos-io/thanos","slug":"s-bad-engine","errorCode":null,"errorMessage":"'%s' bad engine","messagePattern":"'(.+?)' bad engine","errorType":"validation","errorClass":"api.ApiError","httpStatus":400,"severity":"error","filePath":"pkg/api/query/v1.go","lineNumber":318,"sourceCode":"\t\t\treturn false, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Wrapf(err, \"'%s' parameter\", DedupParam)}\n\t\t}\n\t}\n\treturn enableDeduplication, nil\n}\n\nfunc (qapi *QueryAPI) parseQueryParam(r *http.Request) string {\n\treturn r.FormValue(QueryParam)\n}\n\nfunc (qapi *QueryAPI) parseEngineParam(r *http.Request) (e PromqlEngineType, _ *api.ApiError) {\n\tparam := PromqlEngineType(r.FormValue(EngineParam))\n\tif param == \"\" {\n\t\tparam = qapi.defaultEngine\n\t}\n\tswitch param {\n\tcase PromqlEnginePrometheus, PromqlEngineThanos:\n\tdefault:\n\t\treturn param, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf(\"'%s' bad engine\", param)}\n\t}\n\n\treturn param, nil\n}\n\nfunc (qapi *QueryAPI) parseReplicaLabelsParam(r *http.Request) (replicaLabels []string, _ *api.ApiError) {\n\tif err := r.ParseForm(); err != nil {\n\t\treturn nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, \"parse form\")}\n\t}\n\n\treplicaLabels = qapi.replicaLabels\n\t// Overwrite the cli flag when provided as a query parameter.\n\tif len(r.Form[ReplicaLabelsParam]) > 0 {\n\t\treplicaLabels = r.Form[ReplicaLabelsParam]\n\t}\n\treturn replicaLabels, nil\n}\n","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/api/query/v1.go#L300-L336","documentation":"parseEngineParam validates the 'engine' query parameter against the two supported engines (PromQL 'prometheus' and Thanos 'thanos'); any other value is rejected with ErrorBadData. The message echoes the offending engine name.","triggerScenarios":"Passing engine=<anything else> on /api/v1/query, /api/v1/query_range or their explain endpoints, e.g. engine=thanos-impl2, engine=PROMETHEUS (case mismatch), or engine=jq.","commonSituations":"Copying engine options from other engines/tools; attempting to select experimental engines not present in the deployed Thanos version; case-sensitivity mistakes.","solutions":["Use exactly 'prometheus' or 'thanos' (lowercase) for the engine parameter","Omit the parameter to use the server's default engine (-query.promql-engine flag)","Check the Thanos version's supported engine constants (PromqlEnginePrometheus/PromqlEngineThanos)","Fix casing in generated clients"],"exampleFix":"// before\nGET /api/v1/query?query=up&engine=Thanos\n// after\nGET /api/v1/query?query=up&engine=thanos","handlingStrategy":"validation","validationCode":"const ENGINES = new Set(['prometheus','thanos']);\nif (engine !== undefined && !ENGINES.has(engine)) throw new Error(`bad engine: ${engine}`);","typeGuard":"function isKnownEngine(e) { return e === 'prometheus' || e === 'thanos'; }","tryCatchPattern":"try {\n  const res = await fetch(urlWithEngine);\n  const body = await res.json();\n  if (body.errorType === 'bad_data' && /bad engine/.test(body.error)) throw new Error(body.error);\n} catch (e) {\n  if (/bad engine/.test(e.message)) { /* drop the engine param (use server default) and retry */ }\n  throw e;\n}","preventionTips":["Use a closed enum for engine values","Drop the engine param to accept the server default","Check the deployed Thanos version's supported engines","Enforce lowercase when building the URL"],"tags":["http-api","query-parameter","enum","thanos"],"backgroundTag":"invalid-enum-value","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}