{"record":{"id":"6f0b9a53155ae061","repo":"gastownhall/beads","slug":"write-metadata-json-w","errorCode":null,"errorMessage":"write metadata.json: %w","messagePattern":"write metadata\\.json: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/bootstrap.go","lineNumber":835,"sourceCode":"\t// required by configfile.Load consumers.\n\tcfg.Backend = configfile.BackendDolt\n\tcfg.DoltDatabase = dbName\n\tswitch {\n\tcase cfg.IsDoltProxiedServerMode():\n\t\tcfg.DoltMode = configfile.DoltModeProxiedServer\n\tcase cfg.IsDoltServerMode() || doltserver.IsSharedServerMode():\n\t\tcfg.DoltMode = configfile.DoltModeServer\n\tdefault:\n\t\tcfg.DoltMode = configfile.DoltModeEmbedded\n\t}\n\t// Mirror init's convention: metadata.json database points at the Dolt\n\t// directory rather than the legacy \"beads.db\" placeholder.\n\tif cfg.Database == \"\" || cfg.Database == beads.CanonicalDatabaseName {\n\t\tcfg.Database = \"dolt\"\n\t}\n\n\tif err := cfg.Save(beadsDir); err != nil {\n\t\treturn fmt.Errorf(\"write metadata.json: %w\", err)\n\t}\n\n\tif err := createConfigYaml(beadsDir, false, \"\"); err != nil {\n\t\treturn fmt.Errorf(\"create config.yaml: %w\", err)\n\t}\n\tif err := doctor.EnsureGitignoreForBeadsDir(beadsDir); err != nil {\n\t\treturn fmt.Errorf(\"ensure .beads/.gitignore: %w\", err)\n\t}\n\n\t// Persist sync.remote so subsequent fresh clones (and bd bootstrap\n\t// retries) can rediscover the remote without re-probing origin refs.\n\tif syncRemote != \"\" {\n\t\tif err := config.SetYamlConfigInDir(beadsDir, \"sync.remote\", syncRemote); err != nil {\n\t\t\treturn fmt.Errorf(\"persist sync.remote to config.yaml: %w\", err)\n\t\t}\n\t}\n\n\treturn nil","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/bootstrap.go#L817-L853","documentation":"In `finalizeSyncedBootstrap`, after a synced bootstrap the config (`metadata.json`) is updated so the database field points at the Dolt database name (defaulting to `\"dolt\"` rather than the legacy placeholder). If `cfg.Save(beadsDir)` fails to write metadata.json, the error is wrapped as `write metadata.json: ...` and bootstrap finalization aborts.","triggerScenarios":"`bd bootstrap` finishing a sync action calls `finalizeSyncedBootstrap`; saving the updated config fails — `.beads` directory not writable, disk full, metadata.json exists as a directory, or permission conflicts.","commonSituations":"Read-only or root-owned `.beads` after cloning with sudo; a stray `metadata.json/` directory; interrupted earlier bootstrap leaving bad permissions; CI running as a different user than the clone owner.","solutions":["Check writability of `.beads/metadata.json`: fix ownership/permissions (`chown -R $USER .beads`).","If metadata.json is a directory or corrupt, remove it and re-run `bd bootstrap` (it will rewrite config files).","Free disk space if the wrapped error reports I/O or no-space failures.","Re-run `bd bootstrap` — finalization is designed to be idempotent (see TestFinalizeSyncedBootstrapIsIdempotent)."],"exampleFix":"// before (shell)\n$ sudo bd bootstrap   # .beads now owned by root\n$ bd bootstrap        // write metadata.json: open ...: permission denied\n// after\n$ sudo chown -R $USER .beads\n$ bd bootstrap        # succeeds","handlingStrategy":"validation","validationCode":"# Pre-flight before finalize (bootstrap) runs:\nBEADS_DIR=.beads\n[ -d \"$BEADS_DIR\" ] || { echo \"missing $BEADS_DIR\"; exit 1; }\nif [ -e \"$BEADS_DIR/metadata.json\" ] && [ -d \"$BEADS_DIR/metadata.json\" ]; then echo \"metadata.json is a directory\"; exit 1; fi\n[ -w \"$BEADS_DIR\" ] || { echo \"$BEADS_DIR not writable by $(whoami)\"; exit 1; }","typeGuard":null,"tryCatchPattern":"if err := finalizeSyncedBootstrap(ctx, beadsDir, plan, cfg); err != nil {\n    if strings.Contains(err.Error(), \"write metadata.json:\") {\n        // finalization is idempotent — fix permissions and re-run bootstrap\n        return fmt.Errorf(\"repair .beads permissions, then re-run bd bootstrap: %w\", err)\n    }\n    return err\n}","preventionTips":["Avoid running bootstrap under sudo; if you must, chown `.beads` back afterwards.","Ensure `.beads/metadata.json` is a regular writable file, not a directory.","Check disk space before long-running bootstrap operations.","Re-running `bd bootstrap` after fixing permissions is safe (idempotent finalization)."],"tags":["bootstrap","config","filesystem","permissions"],"backgroundTag":"config-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}