{"record":{"id":"f3a262b6f093cf1c","repo":"gastownhall/beads","slug":"not-status-only-supports-operator","errorCode":null,"errorMessage":"NOT status only supports = operator","messagePattern":"NOT status only supports = operator","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/query/evaluator.go","lineNumber":592,"sourceCode":"\t\tif err := json.Unmarshal(i.Metadata, &data); err != nil {\n\t\t\treturn false\n\t\t}\n\t\t_, ok := data[key]\n\t\treturn ok\n\t}, nil\n}\n\n// applyNot applies a NOT expression to the filter.\nfunc (e *Evaluator) applyNot(not *NotNode, filter *types.IssueFilter) error {\n\tcomp, ok := not.Operand.(*ComparisonNode)\n\tif !ok {\n\t\treturn fmt.Errorf(\"NOT only supports simple comparisons in filter mode\")\n\t}\n\n\tswitch comp.Field {\n\tcase \"status\":\n\t\tif comp.Op != OpEquals {\n\t\t\treturn fmt.Errorf(\"NOT status only supports = operator\")\n\t\t}\n\t\tstatus := types.Status(strings.ToLower(comp.Value))\n\t\tfilter.ExcludeStatus = append(filter.ExcludeStatus, status)\n\t\treturn nil\n\tcase \"type\":\n\t\tif comp.Op != OpEquals {\n\t\t\treturn fmt.Errorf(\"NOT type only supports = operator\")\n\t\t}\n\t\tissueType := types.IssueType(strings.ToLower(comp.Value))\n\t\tfilter.ExcludeTypes = append(filter.ExcludeTypes, issueType)\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"NOT not supported for field %s in filter mode\", comp.Field)\n\t}\n}\n\n// parseTimeValue parses a time value from a comparison node.\n// Supports duration values (7d, 24h) which are interpreted as \"now - duration\".","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/query/evaluator.go#L574-L610","documentation":"NOT status in filter mode maps to appending to filter.ExcludeStatus, which is only defined for exact status equality. Any other operator (!=, =~, IN) on NOT status is rejected with this error. Note the asymmetry: plain status supports more operators, but the NOT path only implements =.","triggerScenarios":"A query like `NOT status!=open` or `NOT status=~in_progress` reaching applyNot's status case with comp.Op != OpEquals.","commonSituations":"Double negation attempts ('NOT status!=open' meaning status=open); users expecting regex exclusion support; generated queries combining NOT with inequality operators.","solutions":["Use `NOT status=open` (excludes that status) — the only supported NOT status form","For 'NOT status!=open' (double negation), simply write `status=open`","For regex or IN semantics on status, use the positive form `status=~...` / `status IN (...)` without NOT","Combine multiple `NOT status=x` clauses to exclude several statuses"],"exampleFix":"// before\nbd list 'NOT status!=open'\n// after\nbd list 'status=open'  # or NOT status=open for exclusion","handlingStrategy":"validation","validationCode":"if field == \"status\" && negated && op != \"=\" {\n    return fmt.Errorf(\"NOT status requires = (got %s)\", op)\n}","typeGuard":"func notStatusValid(op string) bool { return op == \"=\" }","tryCatchPattern":null,"preventionTips":["Write NOT status=<value> only","Collapse NOT status!=x double negations into status=x","Use positive regex/IN operators on status without NOT"],"tags":["query","not-operator","status"],"backgroundTag":"query-operator-not-supported","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}