{"record":{"id":"6209959a15ff1111","repo":"gastownhall/beads","slug":"waits-for-metadata-is-not-a-well-formed-gate-objec","errorCode":null,"errorMessage":"waits-for metadata is not a well-formed gate object: %w","messagePattern":"waits-for metadata is not a well-formed gate object: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/batch_apply.go","lineNumber":377,"sourceCode":"//\n// Every other edge type's metadata is passed through unchanged, checked only\n// for being well-formed JSON when it is present at all: the blob is\n// type-specific and this role does not know the types.\nfunc normalizeApplyEdgeMetadata(depType types.DependencyType, metadata string) (string, error) {\n\ttrimmed := strings.TrimSpace(metadata)\n\tif depType != types.DepWaitsFor {\n\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":359,"sourceCodeEnd":393,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/batch_apply.go#L359-L393","documentation":"For waits-for dependencies, edge metadata must unmarshal into types.WaitsForMeta (a gate object). This error wraps the json.Unmarshal failure, meaning the metadata is syntactically broken or not a JSON object shape compatible with WaitsForMeta.","triggerScenarios":"Adding a waits-for dependency whose metadata string fails json.Unmarshal into WaitsForMeta — malformed JSON, or a JSON array/string/number instead of an object.","commonSituations":"Passing \"[\\\"gate\\\"]\" or a bare quoted string as metadata; forgetting to serialize a WaitsForMeta struct before storing; older metadata formats that no longer match the WaitsForMeta schema.","solutions":["Construct a types.WaitsForMeta value and json.Marshal it instead of hand-writing the string","Ensure metadata is a JSON object with the expected gate field","Validate the JSON with json.Valid and unmarshal into WaitsForMeta locally first"],"exampleFix":"// before\nmeta := \"all-children\"\n// after\nraw, _ := json.Marshal(types.WaitsForMeta{Gate: types.WaitsForAllChildren})\nmeta := string(raw)","handlingStrategy":"validation","validationCode":"var m types.WaitsForMeta\nif err := json.Unmarshal([]byte(meta), &m); err != nil {\n\treturn fmt.Errorf(\"bad waits-for metadata: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"waits-for metadata is not a well-formed gate object\") {\n\t// re-encode metadata from types.WaitsForMeta and retry\n}","preventionTips":["Serialize types.WaitsForMeta structs instead of hand-writing JSON","Verify metadata is a JSON object, not an array or string","Test dep-add payloads against a local proxy first"],"tags":["json","waits-for","gate-metadata"],"backgroundTag":"invalid-waits-for-gate-object","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}