{"record":{"id":"faffc3df720c8cb6","repo":"gastownhall/beads","slug":"s-has-unsupported-migration-state-q","errorCode":null,"errorMessage":"%s has unsupported migration state %q","messagePattern":"(.+?) has unsupported migration state %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/migrate_hooks_apply.go","lineNumber":223,"sourceCode":"\tif hook.ReadError != \"\" {\n\t\treturn fmt.Sprintf(\"%s (%s): %s\", hook.Name, hook.State, hook.ReadError)\n\t}\n\treturn fmt.Sprintf(\"%s (%s): %s\", hook.Name, hook.State, suggestion)\n}\n\nfunc chooseHookMigrationWriteSource(hook doctor.HookMigrationHookPlan) (hookMigrationWriteSource, string, error) {\n\tswitch hook.State {\n\tcase \"legacy_only\":\n\t\treturn hookMigrationWriteFromTemplate, \"\", nil\n\tcase \"legacy_with_old_sidecar\", \"legacy_with_both_sidecars\", \"missing_with_old_sidecar\", \"missing_with_both_sidecars\":\n\t\treturn hookMigrationWriteFromOld, hook.HookPath + \".old\", nil\n\tcase \"legacy_with_backup_sidecar\", \"missing_with_backup_sidecar\":\n\t\treturn hookMigrationWriteFromBackup, hook.HookPath + \".backup\", nil\n\tcase \"custom_with_sidecars\":\n\t\treturn hookMigrationWriteFromHookFile, hook.HookPath, nil\n\tdefault:\n\t\tif hook.NeedsMigration {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"%s has unsupported migration state %q\", hook.Name, hook.State)\n\t\t}\n\t\treturn \"\", \"\", fmt.Errorf(\"%s does not require migration\", hook.Name)\n\t}\n}\n\ntype preparedHookWrite struct {\n\tHookName string\n\tPath     string\n\tContent  []byte\n}\n\nfunc applyHookMigrationExecution(execPlan hookMigrationExecutionPlan) (hookMigrationApplySummary, error) {\n\tif len(execPlan.BlockingErrors) > 0 {\n\t\treturn hookMigrationApplySummary{}, fmt.Errorf(\n\t\t\t\"hook migration blocked by %d issue(s): %s\",\n\t\t\tlen(execPlan.BlockingErrors),\n\t\t\tstrings.Join(execPlan.BlockingErrors, \"; \"),\n\t\t)","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/migrate_hooks_apply.go#L205-L241","documentation":"chooseHookMigrationWriteSource maps a git hook's detected migration State to a write-source strategy (template, hook file, old sidecar, backup sidecar). This error is thrown in the default case when the hook reports NeedsMigration=true but its State string is not one of the recognized states, meaning the planner has no strategy for how to produce the migrated content.","triggerScenarios":"A hook whose State (computed by the migration detector) is an unrecognized value while NeedsMigration is true — i.e. detection marked the hook dirty but produced a state label the apply planner doesn't handle.","commonSituations":"A bd version mismatch where the detector writes new state labels the older apply code doesn't know; manually edited hooks producing a hybrid state; corrupted or foreign sidecar files confusing state detection.","solutions":["Re-run detection (`bd migrate hooks` plan/dry-run) so state is recomputed with the current binary","Update bd to the latest version so detector and planner state vocabularies match","Inspect the hook directory for unexpected files (.old/.backup sidecars) and remove stale ones","If persistently stuck, delete the hook and let migration install it fresh from the template"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before apply, inspect the plan\nconst knownStates = new Set(['legacy','legacy_with_old','legacy_with_backup_sidecar','legacy_with_both_sidecars','missing_with_backup_sidecar','custom_with_sidecars']);\nif (hook.NeedsMigration && !knownStates.has(hook.State)) throw new Error(`unsupported state ${hook.State}`);","typeGuard":null,"tryCatchPattern":"if err := applyMigration(hook); err != nil && strings.Contains(err.Error(), \"unsupported migration state\") {\n    // fall back to full re-install from template\n}","preventionTips":["Run the plan/dry-run first and review states","Keep bd updated so detector and planner agree","Clean stale sidecar files so state detection stays unambiguous"],"tags":["migration","git-hooks","state-machine"],"backgroundTag":"unsupported-migration-state","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}