{"record":{"id":"000e2396af19e71f","repo":"bytebase/bytebase","slug":"category-value-must-be-a-string-got-t","errorCode":null,"errorMessage":"category value must be a string, got %T","messagePattern":"category value must be a string, got %T","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/api/v1/release_service.go","lineNumber":495,"sourceCode":"\n\treturn category, nil\n}\n\n// extractCategoryFromExpr walks the CEL AST to extract the category value.\nfunc extractCategoryFromExpr(expr celast.Expr) (string, error) {\n\tswitch expr.Kind() {\n\tcase celast.CallKind:\n\t\tcall := expr.AsCall()\n\t\tfunctionName := call.FunctionName()\n\n\t\t// Handle: category == \"value\"\n\t\tif functionName == celoperators.Equals {\n\t\t\tvariable, value := getVariableAndValueFromExpr(expr)\n\t\t\tif variable == \"category\" {\n\t\t\t\tif categoryValue, ok := value.(string); ok {\n\t\t\t\t\treturn categoryValue, nil\n\t\t\t\t}\n\t\t\t\treturn \"\", errors.Errorf(\"category value must be a string, got %T\", value)\n\t\t\t}\n\t\t\treturn \"\", errors.Errorf(\"unsupported filter variable: %s\", variable)\n\t\t}\n\n\t\treturn \"\", errors.Errorf(\"unsupported operator: %s (only '==' is supported)\", functionName)\n\n\tdefault:\n\t\treturn \"\", errors.Errorf(\"unsupported expression type\")\n\t}\n}\n\nfunc renderTrain(template, timezone string, t time.Time) (string, error) {\n\t// Validate template\n\tif err := validateTemplate(template); err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Validate timezone","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/release_service.go#L477-L513","documentation":"extractCategoryFromExpr requires the value compared against 'category' to be a CEL string literal. When the AST contains category == <something else> (int, bool, list, bytes), it throws this typed error including the Go type of the offending value.","triggerScenarios":"ListReleases with filter like category == 123, category == true, or category == [\"a\"]. The variable is recognized but the value fails the string type assertion.","commonSituations":"Generated clients passing numeric category IDs; accidental unquoted literal in the filter string; confusion between a category name (string) and an internal numeric ID.","solutions":["Quote the category value in the filter so it is a CEL string: category == \"my-category\".","Confirm the exact category name via ListReleaseCategories and use that string verbatim.","If a non-string category identifier is genuinely needed, extend the parser or the API contract."],"exampleFix":"// before\nfilter = \"category == 42\"\n// after\nfilter = \"category == \\\"42\\\"\"","handlingStrategy":"validation","validationCode":"const m = filter.match(/^category\\s*==\\s*(.+)$/);\nif (!m || !/^\"[^\"]*\"$/.test(m[1].trim())) throw new Error('category value must be a quoted string');","typeGuard":null,"tryCatchPattern":"try {\n  const resp = await client.listReleases({ filter });\n} catch (err) {\n  if (err.message?.includes('must be a string')) {\n    filter = `category == \"${String(rawCategoryValue)}\"`;\n  }\n}","preventionTips":["Always quote the category value in the filter","Pass category names, not numeric IDs","Build the filter with a helper that serializes values as CEL strings","Confirm the exact category string via ListReleaseCategories first"],"tags":["cel","filter","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}