{"record":{"id":"44d2e257c31ac253","repo":"gastownhall/beads","slug":"waits-for-gate-q-is-neither-q-nor-q","errorCode":null,"errorMessage":"waits-for gate %q is neither %q nor %q","messagePattern":"waits-for gate %q is neither %q nor %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/batch_apply.go","lineNumber":384,"sourceCode":"\t\tif trimmed == \"\" {\n\t\t\treturn \"\", nil\n\t\t}\n\t\tif !json.Valid([]byte(trimmed)) {\n\t\t\treturn \"\", fmt.Errorf(\"edge metadata is not well-formed JSON\")\n\t\t}\n\t\treturn metadata, nil\n\t}\n\tmeta := types.WaitsForMeta{}\n\tif trimmed != \"\" && trimmed != \"{}\" {\n\t\tif err := json.Unmarshal([]byte(trimmed), &meta); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"waits-for metadata is not a well-formed gate object: %w\", err)\n\t\t}\n\t}\n\tif meta.Gate == \"\" {\n\t\tmeta.Gate = types.WaitsForAllChildren\n\t}\n\tif !types.IsValidWaitsForGate(meta.Gate) {\n\t\treturn \"\", fmt.Errorf(\"waits-for gate %q is neither %q nor %q\",\n\t\t\tmeta.Gate, types.WaitsForAllChildren, types.WaitsForAnyChildren)\n\t}\n\traw, err := json.Marshal(meta)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"serializing waits-for metadata: %w\", err)\n\t}\n\treturn string(raw), nil\n}\n","sourceCodeStart":366,"sourceCodeEnd":393,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/batch_apply.go#L366-L393","documentation":"After unmarshalling waits-for metadata, the gate field must be one of the two supported gate kinds: WaitsForAllChildren or WaitsForAnyChildren. This error means the gate value supplied is something else (empty is auto-defaulted to all-children, so this fires only for unrecognized non-empty values).","triggerScenarios":"Supplying waits-for metadata with gate set to an unknown string such as \"all\", \"any-child\", \"first\", or a typo like \"allchildren\".","commonSituations":"Free-text gate names from CLI flags or config; renaming/refactoring of gate constants leaving stale stored values; copying examples from older docs.","solutions":["Use the exported constants types.WaitsForAllChildren or types.WaitsForAnyChildren as the gate value","Check the exact constant strings with godoc or grep before writing gate names by hand","Drop the gate field entirely — empty is defaulted to WaitsForAllChildren"],"exampleFix":"// before\nmeta := `{\"gate\":\"all\"}`\n// after\nmeta := fmt.Sprintf(`{\"gate\":%q}`, types.WaitsForAllChildren)","handlingStrategy":"validation","validationCode":"if g := meta.Gate; g != \"\" && !types.IsValidWaitsForGate(g) {\n\treturn fmt.Errorf(\"unsupported gate %q\", g)\n}","typeGuard":"func gateKnown(s string) bool { return s == \"\" || types.IsValidWaitsForGate(s) }","tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"waits-for gate \") {\n\t// rewrite gate to types.WaitsForAllChildren and retry\n}","preventionTips":["Only use the exported WaitsForAllChildren / WaitsForAnyChildren constants","Rely on the empty-gate default instead of inventing values","Grep docs for the canonical gate strings before hardcoding"],"tags":["validation","waits-for","gate"],"backgroundTag":"invalid-waits-for-gate-value","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}