{"record":{"id":"1f33ffaa689fdfc1","repo":"gastownhall/beads","slug":"invalid-boolean-value-s","errorCode":null,"errorMessage":"invalid boolean value: %s","messagePattern":"invalid boolean value: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/query/evaluator.go","lineNumber":1033,"sourceCode":"\tcase OpEquals:\n\t\treturn func(i *types.Issue) bool { return i.SpecID == value }, nil\n\tcase OpNotEquals:\n\t\treturn func(i *types.Issue) bool { return i.SpecID != value }, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"spec does not support %s operator\", comp.Op.String())\n\t}\n}\n\nfunc (e *Evaluator) buildBoolPredicate(comp *ComparisonNode, getter func(*types.Issue) bool) (func(*types.Issue) bool, error) {\n\tval := strings.ToLower(comp.Value)\n\tvar boolVal bool\n\tswitch val {\n\tcase \"true\", \"yes\", \"1\":\n\t\tboolVal = true\n\tcase \"false\", \"no\", \"0\":\n\t\tboolVal = false\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid boolean value: %s\", comp.Value)\n\t}\n\n\tswitch comp.Op {\n\tcase OpEquals:\n\t\treturn func(i *types.Issue) bool { return getter(i) == boolVal }, nil\n\tcase OpNotEquals:\n\t\treturn func(i *types.Issue) bool { return getter(i) != boolVal }, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"boolean field does not support %s operator\", comp.Op.String())\n\t}\n}\n\n// Evaluate is a convenience function that parses and evaluates a query string.\nfunc Evaluate(query string) (*QueryResult, error) {\n\treturn EvaluateAt(query, time.Now())\n}\n\n// EvaluateAt parses and evaluates a query string with a specific reference time.","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/query/evaluator.go#L1015-L1051","documentation":"Boolean fields (via buildBoolPredicate) accept only truthy/falsy literals: true/yes/1 and false/no/0 (case-insensitive). Any other value — including on/off, enabled, T/F, or a non-boolean token — triggers this error before the predicate is built.","triggerScenarios":"Queries like `pinned = on`, `blocked = enabled`, or `ready = \"TRUE \"` (with stray characters); a boolean comparison whose right-hand side does not normalize to one of the six accepted literals.","commonSituations":"SQL habits (bit values 1/0 are fine, but TRUE/FALSE spelled as T/F are not); config-file style on/off values; extra quotes or whitespace surviving shell escaping; passing numbers other than 1/0.","solutions":["Rewrite the value as true/false, yes/no, or 1/0 (case-insensitive).","Trim quotes and whitespace around the value in the query string.","Check the %s in the message to see exactly what token was received — often a shell-escaping artifact.","Fix UI/script generators to emit canonical true/false for boolean query fields."],"exampleFix":"// before\nbd list --query \"pinned = on\"\n// after\nbd list --query \"pinned = true\"   // or yes / 1","handlingStrategy":"validation","validationCode":"var boolLiterals = map[string]bool{\n\t\"true\": true, \"yes\": true, \"1\": true,\n\t\"false\": false, \"no\": false, \"0\": false,\n}\nfunc validBoolValue(v string) bool {\n\t_, ok := boolLiterals[strings.ToLower(strings.TrimSpace(v))]\n\treturn ok\n}","typeGuard":"func asBoolLiteral(v string) (bool, bool) {\n\tb, ok := boolLiterals[strings.ToLower(strings.TrimSpace(v))]\n\treturn b, ok\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid boolean value\") {\n\treturn fmt.Errorf(\"use true/false, yes/no, or 1/0: %w\", err)\n}","preventionTips":["Normalize on/off or T/F inputs to true/false before query building","Trim whitespace and quotes from user-supplied values","Maintain an allowlist of boolean literals in UI dropdowns","Test boolean query fields with all six accepted literals"],"tags":["query","boolean","validation"],"backgroundTag":"invalid-boolean-value","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}