{"record":{"id":"579bac77c5e8ee04","repo":"gitbutlerapp/gitbutler","slug":"review-thread-resolution-for-forge-forge-is-not-implemented","errorCode":null,"errorMessage":"Review thread resolution for forge {forge:?} is not implemented yet.","messagePattern":"Review thread resolution for forge (.+?) is not implemented yet\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-forge/src/review.rs","lineNumber":1771,"sourceCode":"pub async fn set_review_thread_resolved(\n    preferred_forge_user: &Option<crate::ForgeUser>,\n    forge_repo_info: &crate::forge::ForgeRepoInfo,\n    thread_id: &str,\n    resolved: bool,\n    storage: &but_forge_storage::Controller,\n) -> Result<()> {\n    match &forge_repo_info.forge {\n        ForgeName::GitHub => {\n            let preferred_account = preferred_forge_user.as_ref().and_then(|user| user.github());\n            but_github::pr::set_review_thread_resolved(\n                preferred_account,\n                thread_id,\n                resolved,\n                storage,\n            )\n            .await\n        }\n        forge => Err(anyhow::anyhow!(\n            \"Review thread resolution for forge {forge:?} is not implemented yet.\"\n        )),\n    }\n}\n\n/// Reply into an existing review thread, returning the comment it made.\n///\n/// Addressed by the thread's own forge id rather than the review number: a\n/// reply belongs to a conversation, not to the review it hangs on.\npub async fn create_review_thread_reply(\n    preferred_forge_user: &Option<crate::ForgeUser>,\n    forge_repo_info: &crate::forge::ForgeRepoInfo,\n    thread_id: &str,\n    body: &str,\n    storage: &but_forge_storage::Controller,\n) -> Result<ForgeReviewThreadComment> {\n    let crate::forge::ForgeRepoInfo { forge, .. } = forge_repo_info;\n    match forge {","sourceCodeStart":1753,"sourceCodeEnd":1789,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-forge/src/review.rs#L1753-L1789","documentation":"but-forge's review API dispatches on the ForgeName of the repository. Only GitHub has an implementation for resolving (resolving/unresolving) a review thread; every other forge (GitLab, Bitbucket, Azure) falls into a catch-all arm that returns this anyhow error. The library throws it to fail loudly instead of silently pretending the operation succeeded.","triggerScenarios":"Calling the review-thread resolution function (crates/but-forge/src/review.rs, resolve-thread path) with a forge whose ForgeName is GitLab, Bitbucket, or Azure — i.e. any non-GitHub repo connection.","commonSituations":"Working in a GitButler workspace connected to a GitLab, Bitbucket, or Azure DevOps remote and trying to resolve a review/PR thread from the UI or API. Also occurs when a repo is misclassified as a non-GitHub forge or when new forge support has been added for reads but not yet for thread resolution.","solutions":["Perform thread resolution only for GitHub-backed repositories; hide or disable resolve controls for other forges.","Check the repository's forge (ForgeName) before calling and route non-GitHub forges to their native UI or API instead.","If support is needed, implement the GitLab/Bitbucket/Azure arm in crates/but-forge/src/review.rs or file/track upstream work for that forge."],"exampleFix":"// before\nforge::resolve_review_thread(forge, review_number, thread_id, resolved, storage).await?;\n\n// after\nif forge != ForgeName::GitHub {\n    return Err(anyhow::anyhow!(\"thread resolution is only supported for GitHub\"));\n}\nforge::resolve_review_thread(forge, review_number, thread_id, resolved, storage).await?;","handlingStrategy":"fallback","validationCode":"if (forge !== 'github') { throw new SkipOperation(`thread resolution unsupported for ${forge}`); }","typeGuard":"const isGitHub = (forge: ForgeName): forge is 'github' => forge === 'github';","tryCatchPattern":"try { await resolveThread(...) } catch (e) { if (String(e).includes('not implemented yet')) { showUnsupportedForgeNotice('resolve thread'); } else { throw e; } }","preventionTips":["Check ForgeName before calling any forge review write API","Feature-flag forge capabilities per provider in the UI (capabilities/checks pattern)","Track which review operations each forge supports in one capability table"],"tags":["forge","review-thread","unimplemented"],"backgroundTag":"method-not-implemented","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}