{"record":{"id":"e7d873d130c0bcc8","repo":"gastownhall/beads","slug":"or-not-supported-for-this-field-combination","errorCode":null,"errorMessage":"OR not supported for this field combination","messagePattern":"OR not supported for this field combination","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/query/evaluator.go","lineNumber":150,"sourceCode":"func (e *Evaluator) buildFilter(node Node, filter *types.IssueFilter) error {\n\tswitch n := node.(type) {\n\tcase *ComparisonNode:\n\t\treturn e.applyComparison(n, filter)\n\tcase *AndNode:\n\t\tif err := e.buildFilter(n.Left, filter); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn e.buildFilter(n.Right, filter)\n\tcase *NotNode:\n\t\treturn e.applyNot(n, filter)\n\tcase *OrNode:\n\t\t// Only reached for LabelsAny optimization\n\t\tlabels := e.collectOrLabels(n)\n\t\tif labels != nil {\n\t\t\tfilter.LabelsAny = append(filter.LabelsAny, labels...)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"OR not supported for this field combination\")\n\tdefault:\n\t\treturn fmt.Errorf(\"unexpected node type: %T\", node)\n\t}\n}\n\n// applyComparison applies a comparison to the filter.\nfunc (e *Evaluator) applyComparison(comp *ComparisonNode, filter *types.IssueFilter) error {\n\tswitch comp.Field {\n\tcase \"status\":\n\t\treturn e.applyStatusFilter(comp, filter)\n\tcase \"priority\":\n\t\treturn e.applyPriorityFilter(comp, filter)\n\tcase \"type\":\n\t\treturn e.applyTypeFilter(comp, filter)\n\tcase \"assignee\":\n\t\treturn e.applyAssigneeFilter(comp, filter)\n\tcase \"owner\":\n\t\treturn e.applyOwnerFilter(comp, filter)","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/query/evaluator.go#L132-L168","documentation":"During filter construction the query evaluator reaches an OrNode that could not be converted into the LabelsAny fast-path: collectOrLabels returned nil because the OR chain mixes non-label comparisons (e.g. status=open OR priority=1). The storage-backed filter has no representation for that OR shape, so buildFilter returns this error instead of silently producing wrong results.","triggerScenarios":"Evaluate/buildFilter receiving a parsed filter expression where an OR contains comparisons on fields other than label/labels with OpEquals — e.g. (status = open OR priority = 1) or (label = x OR title contains y).","commonSituations":"Users writing filter strings with OR across heterogeneous fields; programmatic ASTs combining OR with non-equality operators; after upgrading, previously lenient parsers now emit OrNodes the optimizer can't collapse.","solutions":["Rewrite the filter so OR only chains label=X comparisons (those become LabelsAny)","Split into multiple queries (one per OR branch) and union results client-side","Use AND where semantics allow, since AND is fully supported by buildFilter","If you control the query construction, only emit OrNodes after checking canUseLabelsAnyOptimization / collectOrLabels"],"exampleFix":"// before\n// filter: \"status = open OR priority = 1\"\n// after\n// run two filtered queries and merge:\n//   \"status = open\"\n//   \"priority = 1\"\n// or restrict ORs to: \"label = a OR label = b\"","handlingStrategy":"validation","validationCode":"// Only emit OR nodes whose branches are all label equality comparisons\nfunc orIsLabelOnly(n *query.OrNode, ev *query.Evaluator) bool {\n    return ev.CanUseLabelsAnyOptimization(n)\n}","typeGuard":"func buildSafeFilter(n query.Node, f *types.IssueFilter) error {\n    if or, ok := n.(*query.OrNode); ok && !canUseLabelsAny(or) {\n        return fmt.Errorf(\"unsupported OR; rewrite as label-only OR or split queries\")\n    }\n    return nil\n}","tryCatchPattern":"if err := evaluator.Evaluate(ast); err != nil {\n    if strings.Contains(err.Error(), \"OR not supported\") {\n        // fallback: split OR into separate queries and merge results\n        return evaluateByParts(ast)\n    }\n    return err\n}","preventionTips":["Document to users that OR is only supported across label equality comparisons","Validate filter strings before parsing: reject OR over non-label fields at the UI layer","Prefer splitting multi-field ORs into multiple queries merged client-side","Add unit tests for every OR shape you intend to support"],"tags":["query","filter","or-operator","unsupported"],"backgroundTag":"unsupported-query-operator","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}