{"record":{"id":"4a4e079986821530","repo":"gastownhall/beads","slug":"failed-to-back-up-s-before-injecting-bd-section","errorCode":null,"errorMessage":"failed to back up %s before injecting bd section: %w","messagePattern":"failed to back up (.+?) before injecting bd section: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/hooks.go","lineNumber":960,"sourceCode":"\t\t\t// Check if file already has section markers\n\t\t\tif strings.Contains(existingStr, hookSectionBeginPrefix) {\n\t\t\t\t// Update only the section between markers\n\t\t\t\tnewContent = injectHookSection(existingStr, section)\n\t\t\t} else {\n\t\t\t\t// Check if this is a legacy bd hook (shim or inline)\n\t\t\t\tversionInfo, _ := getHookVersion(hookPath)\n\t\t\t\tif versionInfo.IsBdHook {\n\t\t\t\t\t// Legacy bd hook — replace entire file with section format\n\t\t\t\t\tnewContent = \"#!/usr/bin/env sh\\n\" + section\n\t\t\t\t} else {\n\t\t\t\t\t// Non-bd hook — this is the one write that modifies a file\n\t\t\t\t\t// bd does not own. Preserve the original as a one-time\n\t\t\t\t\t// .backup sidecar before injecting (bd-5vdt8).\n\t\t\t\t\tbackupPath := hookPath + \".backup\"\n\t\t\t\t\tif _, statErr := os.Lstat(backupPath); os.IsNotExist(statErr) {\n\t\t\t\t\t\t// #nosec G306 -- keep executable so a rename restores a working hook\n\t\t\t\t\t\tif backupErr := os.WriteFile(backupPath, existing, 0755); backupErr != nil {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"failed to back up %s before injecting bd section: %w\", hookName, backupErr)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Inject section, preserving existing content\n\t\t\t\t\tnewContent = injectHookSection(existingStr, section)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Normalize line endings to LF\n\t\tnewContent = strings.ReplaceAll(newContent, \"\\r\\n\", \"\\n\")\n\n\t\t// Write hook file\n\t\t// #nosec G306 -- git hooks must be executable for Git to run them\n\t\tif err := os.WriteFile(hookPath, []byte(newContent), 0755); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write %s: %w\", hookName, err)\n\t\t}\n\t}\n","sourceCodeStart":942,"sourceCodeEnd":978,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/hooks.go#L942-L978","documentation":"When bd must inject its section into a foreign hook it does not own, it first saves a one-time .backup copy of the original (bd-5vdt8). If writing that .backup file fails, the install aborts rather than modify the hook without a backup. The underlying OS write error is wrapped in %w.","triggerScenarios":"installHooksWithOptions detects a foreign (non-bd) hook with content, attempts os.WriteFile(hookPath+\".backup\", existing, 0755), and the write fails — typically because the hooks directory is not writable.","commonSituations":"Read-only or root-owned .git/hooks directory; disk full; a directory named `<hook>.backup` already exists; immutable file attribute set.","solutions":["Fix write permission on the hooks directory (chown/chmod) and re-run","Remove any `<hook>.backup` entry that is a directory or otherwise unwritable","Free disk space if the filesystem is full, then re-run"],"exampleFix":"// before\n$ ls -ld .git/hooks  # drwxr-xr-x root\n// after\n$ sudo chown -R $(whoami) .git/hooks && bd hooks install","handlingStrategy":"validation","validationCode":"[ -w \"$(dirname \"$hook\")\" ] || echo \"hooks dir not writable; .backup would fail\"","typeGuard":null,"tryCatchPattern":"if err := installHooks(...); err != nil { if strings.Contains(err.Error(), \"back up\") { /* restore writability or clear blocking .backup path, then retry */ } }","preventionTips":["Ensure hooks directory is writable before installing foreign hooks","Avoid immutable attributes (chattr +i) on hook paths","Keep disk space above a minimum threshold in CI runners"],"tags":["filesystem","backup","permissions"],"backgroundTag":"backup-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}