{"record":{"id":"1967abf3ff11980b","repo":"gitbutlerapp/gitbutler","slug":"repo-access-failed","errorCode":null,"errorMessage":"repo access failed","messagePattern":"repo access failed","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/setup.rs","lineNumber":656,"sourceCode":"            create_empty_initial_commit(&repo)?;\n\n            writeln!(\n                &mut progress as &mut dyn FmtWrite,\n                \"{}\",\n                t.success\n                    .paint(\"Initialized a new repository and created an empty first commit.\\n\")\n            )?;\n            return Ok(repo);\n        }\n    }\n\n    Err(anyhow::anyhow!(\"No git repository found.\"))\n}\n\nfn create_empty_initial_commit(repo: &gix::Repository) -> anyhow::Result<()> {\n    // In an unborn repo, this returns the well-known empty-tree id.\n    // (It works even if the empty tree object isn’t physically in the ODB.)\n    let empty_tree = repo.head_tree_id_or_empty().expect(\"repo access failed\"); // -> Id<'_>\n    let empty_tree = empty_tree.detach(); // -> ObjectId (optional; commit() accepts Into<ObjectId> anyway)\n\n    // No parents for the first commit. Update HEAD (writes through to refs/heads/main).\n    repo.commit(\n        \"HEAD\",\n        \"Initial empty commit\\n\",\n        empty_tree,\n        std::iter::empty::<gix::hash::ObjectId>(),\n    )?;\n\n    Ok(())\n}\n","sourceCodeStart":638,"sourceCodeEnd":669,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but/src/command/legacy/setup.rs#L638-L669","documentation":"Panic during 'but setup' when initializing a brand-new repository: create_empty_initial_commit calls head_tree_id_or_empty, which for an unborn HEAD returns the well-known empty-tree id but still has to read HEAD through the refdb. The expect ('repo access failed') fires when that read fails - a corrupted or unreadable .git, a HEAD pointing at an unreadable ref, or a concurrent process deleting the repository mid-setup.","triggerScenarios":"Running 'but setup' in a directory whose .git was partially created or corrupted (interrupted git init); filesystem permissions denying reads under .git; antivirus/file locking on Windows removing or locking files mid-run; another process deleting the repo concurrently.","commonSituations":"Interrupted repository initialization; restored-from-backup clones with damaged refs; sandboxed environments blocking .git access; running setup while another git process rewrites refs.","solutions":["Check repository integrity in the same directory: 'git fsck'","Verify read/write permissions on .git for the running user","If .git is a broken remnant, delete it and re-run 'git init' followed by 'but setup'","Avoid running other git processes against the repo during setup"],"exampleFix":"// before\nlet empty_tree = repo.head_tree_id_or_empty().expect(\"repo access failed\");\n\n// after\nlet empty_tree = repo.head_tree_id_or_empty()\n    .map_err(|e| anyhow::anyhow!(\"cannot read HEAD while creating the initial commit: {e}\"))?;","handlingStrategy":"validation","validationCode":"// Pre-flight before setup writes anything: HEAD must be readable\nif repo.find_reference(\"HEAD\").is_err() {\n    anyhow::bail!(\".git is not readable - check permissions or run 'git fsck'\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not run other git processes against a repository during initial setup","Run 'git fsck' after restoring clones from backups or interrupted operations","Ensure the running user owns .git before invoking setup in service contexts"],"tags":["rust","panic","git","setup","head","corruption"],"backgroundTag":"git-head-unresolved","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}