gitbutlerapp/gitbutler · error

Review thread replies for forge

Error message

Review thread replies for forge {forge:?} are not implemented yet.

What it means

The review-thread reply API in but-forge only implements posting a reply for GitHub; the wildcard match arm returns this error for any other forge. It is an explicit 'write operation unsupported on this forge' guard so callers never assume a reply was created when it was not.

Solutions

  1. Restrict thread replies to GitHub repositories and surface an 'unsupported on this forge' message in the UI otherwise.
  2. Gate the reply API call on ForgeName::GitHub before invoking it.
  3. Implement the reply arm for the target forge in crates/but-forge/src/review.rs or wait for upstream forge support.

Example fix

// before
let comment = forge::reply_review_thread(forge, review_number, thread_id, body, storage).await?;

// after
if forge != ForgeName::GitHub {
    eprintln!("thread replies are not supported for this forge");
    return Ok(());
}
let comment = forge::reply_review_thread(forge, review_number, thread_id, body, storage).await?;
Defensive patterns

Strategy: fallback

Validate before calling

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

Type guard

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

Try / catch

try { await replyToThread(...) } catch (e) { if (String(e).includes('not implemented yet')) { disableReplyComposer(); } else { throw e; } }

Prevention

When it happens

Trigger: Replying to an existing review thread via the reply-into-thread function while the repository's ForgeName is GitLab, Bitbucket, or Azure.

Common situations: A developer or user connected to a GitLab merge request, Bitbucket PR, or Azure PR tries to comment on a review thread through the GitButler forge abstraction; or a newly onboarded forge got read paths wired up before the write path for replies.

Related errors


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

Appendix: source

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

    thread_id: &str,
    body: &str,
    storage: &but_forge_storage::Controller,
) -> Result<ForgeReviewThreadComment> {
    let crate::forge::ForgeRepoInfo { forge, .. } = forge_repo_info;
    match forge {
        ForgeName::GitHub => {
            let preferred_account = preferred_forge_user.as_ref().and_then(|user| user.github());
            let comment = but_github::pr::create_review_thread_reply(
                preferred_account,
                thread_id,
                body,
                storage,
            )
            .await?;
            Ok(comment.into())
        }
        // A write, so it fails loudly rather than reading as empty.
        _ => Err(anyhow::anyhow!(
            "Review thread replies for forge {forge:?} are not implemented yet."
        )),
    }
}

/// List the diff-anchored review threads on a review, oldest first. Each
/// call hits the forge fresh (no DB cache).
pub async fn list_review_threads(
    preferred_forge_user: &Option<crate::ForgeUser>,
    forge_repo_info: &crate::forge::ForgeRepoInfo,
    review_number: usize,
    storage: &but_forge_storage::Controller,
) -> Result<Vec<ForgeReviewThread>> {
    let crate::forge::ForgeRepoInfo {
        forge, owner, repo, ..
    } = forge_repo_info;
    match forge {
        ForgeName::GitHub => {

View on GitHub (pinned to 58e5313667)