{"record":{"id":"846db9e008b04fb8","repo":"gastownhall/beads","slug":"config-storage-class-s-w","errorCode":null,"errorMessage":"config storage-class.%s: %w","messagePattern":"config storage-class\\.(.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/create.go","lineNumber":731,"sourceCode":"// The parsed class is returned verbatim, including versioned. The caller must\n// normalize versioned to the unset marker (the marker is omitted when\n// versioned, C2.4) only AFTER plane-conflict validation, so an explicit durable\n// request paired with a wisp-plane flag is rejected rather than silently erased\n// into an effective-ephemeral row. Values are validated wherever they came\n// from: a bad flag is a usage error, a bad config value is a config bug and\n// fails just as loudly.\nfunc resolveStorageClass(explicit string, issueType types.IssueType) (types.StorageClass, error) {\n\traw := explicit\n\tif raw == \"\" {\n\t\traw = config.GetString(\"storage-class.\" + string(issueType))\n\t\tif raw == \"\" {\n\t\t\treturn \"\", nil\n\t\t}\n\t}\n\tclass, err := types.ParseStorageClass(raw)\n\tif err != nil {\n\t\tif explicit == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"config storage-class.%s: %w\", issueType, err)\n\t\t}\n\t\treturn \"\", err\n\t}\n\treturn class, nil\n}\n\n// reconcileStorageClassPlane applies flag-over-config precedence between a\n// resolved storage class and the effective wisp plane (Protocol v0.1 §C1.3).\n// A wisp-plane record is ephemeral by construction, so a durable class\n// (versioned/unversioned) cannot ride on it. explicit reports whether the class\n// came from an explicit flag/field rather than a per-type config default:\n//   - explicit durable class + wisp plane -> conflict=true; the caller rejects\n//     it so the durable intent is preserved rather than silently collapsed into\n//     an effective-ephemeral record;\n//   - config-derived durable class + wisp plane -> cleared, yielding to the\n//     explicit --ephemeral/--no-history plane.\n//\n// versioned normalizes to the unset marker (C2.4) only after the check, so the","sourceCodeStart":713,"sourceCodeEnd":749,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/create.go#L713-L749","documentation":"resolveStorageClass validates the storage-class value after deciding its source: an explicit --storage-class flag failure is returned bare (a usage error), but when the value came from per-type config (storage-class.<type>) and ParseStorageClass rejects it, the error is wrapped with the config key. This makes a bad config value identifiable as a configuration bug rather than a command-line mistake, and it fails loudly per Protocol v0.1 C1.3.","triggerScenarios":"Creating an issue without --storage-class while config key storage-class.<issueType> (e.g. storage-class.bug in beads config or a config file) holds a value types.ParseStorageClass doesn't accept — misspelled class names, wrong case, or an unsupported token.","commonSituations":"Hand-edited config files with `storage-class.bug: durable-ish`; copied configs from docs of a different version; typos like `vesioned` instead of `versioned`; config applied to a type whose key was spelled wrong.","solutions":["Fix the config value for storage-class.<type> to a valid storage class (e.g. versioned/unversioned/ephemeral as accepted by types.ParseStorageClass)","Run with an explicit --storage-class <valid> flag to override the bad config and unblock the create","Print the effective config (`bd config` / config get storage-class.<type>) to confirm which key/value is being read","Align with your team's config template and bd version — older or newer versions may accept different tokens"],"exampleFix":"# before (config)\nstorage-class.bug: durable-ish\n# after\nstorage-class.bug: versioned","handlingStrategy":"validation","validationCode":"// Validate the config value before running bd create\nraw := config.GetString(\"storage-class.\" + issueType)\nif raw != \"\" {\n    if _, err := types.ParseStorageClass(raw); err != nil {\n        return fmt.Errorf(\"storage-class.%s is invalid: %w\", issueType, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"sc, err := resolveStorageClass(explicit, issueType)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"config storage-class.\") {\n        // bad config value: fix config, not the CLI flags\n    }\n    return err // bare error means bad --storage-class flag (usage error)\n}","preventionTips":["Validate storage-class.<type> entries with types.ParseStorageClass at config-load time","Only set the config key with tokens accepted by your bd version (check --help / docs)","Prefer explicit --storage-class when scripting, so config drift can't break creates","Keep team config templates versioned with the bd version that accepts their values"],"tags":["config","storage-class","validation","create"],"backgroundTag":"invalid-config-value","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}