{"record":{"id":"e2b07b652df7be37","repo":"gitbutlerapp/gitbutler","slug":"defaulttargetnotfound","errorCode":"DefaultTargetNotFound","errorMessage":"there is no default target","messagePattern":"there is no default target","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-core/src/ref_metadata.rs","lineNumber":300,"sourceCode":"    match repo.find_reference(target_ref) {\n        Ok(mut target_ref) => {\n            if project_meta.target_commit_id.is_none()\n                && let Ok(commit) = target_ref.peel_to_commit()\n            {\n                project_meta.target_commit_id = Some(commit.id);\n            }\n        }\n        Err(_) => project_meta.target_ref = None,\n    }\n    project_meta\n}\n\nimpl ProjectMeta {\n    /// Return [`Self::target_ref`], or a [`DefaultTargetNotFound`](but_error::Code::DefaultTargetNotFound)\n    /// error if no target is configured.\n    pub fn target_ref_or_err(&self) -> Result<&gix::refs::FullName> {\n        self.target_ref.as_ref().ok_or_else(|| {\n            anyhow::anyhow!(\"there is no default target\")\n                .context(but_error::Code::DefaultTargetNotFound)\n        })\n    }\n\n    /// Return [`Self::target_commit_id`], or a [`DefaultTargetNotFound`](but_error::Code::DefaultTargetNotFound)\n    /// error if no target commit is known.\n    pub fn target_commit_id_or_err(&self) -> Result<gix::ObjectId> {\n        self.target_commit_id.ok_or_else(|| {\n            anyhow::anyhow!(\"there is no default target commit\")\n                .context(but_error::Code::DefaultTargetNotFound)\n        })\n    }\n\n    /// The name of the remote to push to: [`Self::push_remote`], falling back to the\n    /// remote behind [`Self::target_ref`].\n    ///\n    /// If no configured remote matches the target ref, fall back to the first path component\n    /// after `refs/remotes/`, the textual remote name that legacy metadata stored verbatim.","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but-core/src/ref_metadata.rs#L282-L318","documentation":"ProjectMeta::target_ref_or_err returns the workspace's default target branch ref, or fails with Code::DefaultTargetNotFound when project metadata has none configured. Nearly every workspace operation (virtual branches, apply/unapply, push) needs the target, so this usually means 'the project is not set up'. Note the code just above: when the configured target ref can no longer be validated, target_ref is actively set to None — a deleted upstream target branch also lands here.","triggerScenarios":"Any workspace API needing the target branch on a project whose metadata has target_ref = None: brand-new projects before target selection, interrupted setup, or sanitization after the target ref disappeared from the remote.","commonSituations":"The user deleted the default branch on the host; onboarding abandoned before picking a target; corrupted or very old metadata; switching targets mid-operation.","solutions":["Set (or re-select) a target branch via project settings / the workspace API, then retry.","If the target branch was deleted upstream, restore it or choose another existing branch as target.","Catch Code::DefaultTargetNotFound and route the user into the target-setup flow instead of showing a generic error.","Confirm afterwards that target_ref_or_err() succeeds."],"exampleFix":"// before\nlet target = project_meta.target_ref_or_err()?;\n\n// after\nlet target = match project_meta.target_ref_or_err() {\n    Ok(name) => name,\n    Err(err) if is_code(&err, &Code::DefaultTargetNotFound) => {\n        run_target_setup_flow(&ctx)?; // user picks a target\n        ctx.project_meta()?.target_ref_or_err()?\n    }\n    Err(err) => return Err(err),\n};","handlingStrategy":"try-catch","validationCode":"let meta = project_meta(&ctx)?;\nif meta.target_ref.is_none() {\n    // run target setup before any workspace operation\n    return setup_target(&ctx);\n}","typeGuard":null,"tryCatchPattern":"match op_result {\n    Err(err) if err.chain().any(|c| c.downcast_ref::<but_error::Code>()\n        == Some(&but_error::Code::DefaultTargetNotFound)) => setup_target_flow(),\n    other => other,\n}?","preventionTips":["Block workspace actions in the UI until a target branch is configured.","React to target-ref deletion on the remote by prompting re-selection.","Treat DefaultTargetNotFound as a setup-state signal, not a hard failure."],"tags":["workspace","target-branch","metadata","configuration","setup"],"backgroundTag":"missing-default-target","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}