gitbutlerapp/gitbutler · error

Review thread resolution for forge

Error message

Review thread resolution for forge {forge:?} is not implemented yet.

What it means

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.

Solutions

  1. Perform thread resolution only for GitHub-backed repositories; hide or disable resolve controls for other forges.
  2. Check the repository's forge (ForgeName) before calling and route non-GitHub forges to their native UI or API instead.
  3. 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.

Example fix

// before
forge::resolve_review_thread(forge, review_number, thread_id, resolved, storage).await?;

// after
if forge != ForgeName::GitHub {
    return Err(anyhow::anyhow!("thread resolution is only supported for GitHub"));
}
forge::resolve_review_thread(forge, review_number, thread_id, resolved, storage).await?;
Defensive patterns

Strategy: fallback

Validate before calling

if (forge !== 'github') { throw new SkipOperation(`thread resolution unsupported for ${forge}`); }

Type guard

const isGitHub = (forge: ForgeName): forge is 'github' => forge === 'github';

Try / catch

try { await resolveThread(...) } catch (e) { if (String(e).includes('not implemented yet')) { showUnsupportedForgeNotice('resolve thread'); } else { throw e; } }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/579bac77c5e8ee04. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-forge/src/review.rs:1771

pub async fn set_review_thread_resolved(
    preferred_forge_user: &Option<crate::ForgeUser>,
    forge_repo_info: &crate::forge::ForgeRepoInfo,
    thread_id: &str,
    resolved: bool,
    storage: &but_forge_storage::Controller,
) -> Result<()> {
    match &forge_repo_info.forge {
        ForgeName::GitHub => {
            let preferred_account = preferred_forge_user.as_ref().and_then(|user| user.github());
            but_github::pr::set_review_thread_resolved(
                preferred_account,
                thread_id,
                resolved,
                storage,
            )
            .await
        }
        forge => Err(anyhow::anyhow!(
            "Review thread resolution for forge {forge:?} is not implemented yet."
        )),
    }
}

/// Reply into an existing review thread, returning the comment it made.
///
/// Addressed by the thread's own forge id rather than the review number: a
/// reply belongs to a conversation, not to the review it hangs on.
pub async fn create_review_thread_reply(
    preferred_forge_user: &Option<crate::ForgeUser>,
    forge_repo_info: &crate::forge::ForgeRepoInfo,
    thread_id: &str,
    body: &str,
    storage: &but_forge_storage::Controller,
) -> Result<ForgeReviewThreadComment> {
    let crate::forge::ForgeRepoInfo { forge, .. } = forge_repo_info;
    match forge {

View on GitHub (pinned to 58e5313667)