{"record":{"id":"90fd890dbb72a88c","repo":"gitbutlerapp/gitbutler","slug":"listing-ci-checks-for-forge-forge-is-not-imple","errorCode":null,"errorMessage":"Listing ci checks for forge {forge:?} is not implemented yet.","messagePattern":"Listing ci checks for forge (.+?) is not implemented yet\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-forge/src/ci.rs","lineNumber":193,"sourceCode":"                let runtime = tokio::runtime::Runtime::new()\n                    .map_err(|err| anyhow::anyhow!(\"Failed to create tokio runtime: {err}\"))?;\n                runtime.block_on(bb.list_checks_for_ref(&workspace, &repo_slug, &reference))\n            })\n            .join()\n            .map_err(|e| anyhow::anyhow!(\"Failed to join thread: {e:?}\"))??;\n\n            Ok(statuses.map(|statuses| {\n                statuses\n                    .into_iter()\n                    .map(|status| {\n                        let mut ci_check = CiCheck::from(status);\n                        ci_check.reference = reference_for_checks.to_string();\n                        ci_check\n                    })\n                    .collect()\n            }))\n        }\n        _ => Err(anyhow::anyhow!(\n            \"Listing ci checks for forge {forge:?} is not implemented yet.\"\n        )),\n    }\n}\n\n#[derive(Debug, Clone, Serialize)]\n#[cfg_attr(feature = \"export-schema\", derive(schemars::JsonSchema))]\n#[serde(rename_all = \"camelCase\")]\npub struct CiCheck {\n    pub id: i64,\n    pub name: String,\n    pub output: CiOutput,\n    pub started_at: Option<chrono::DateTime<chrono::Utc>>,\n    pub status: CiStatus,\n    pub head_sha: String,\n    pub url: String,\n    pub html_url: String,\n    pub details_url: String,","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-forge/src/ci.rs#L175-L211","documentation":"but-forge's CI-check listing is implemented for GitHub, GitLab and Bitbucket; the match on ForgeName ends in a catch-all arm that errors for any other forge, stating the operation is not implemented yet. Currently that means Azure DevOps remotes cannot list CI checks through this API.","triggerScenarios":"Calling the CI-checks entry point in crates/but-forge/src/ci.rs for a repository whose remote resolves to a ForgeName outside {GitHub, GitLab, Bitbucket} - concretely an Azure DevOps remote.","commonSituations":"Teams self-hosting on Azure DevOps expecting feature parity with GitHub/GitLab; automation that enumerates all remotes and queries CI for each, hitting the unsupported arm.","solutions":["Accept the error and hide/skip CI status for remotes on unsupported forges","Query CI status for those remotes through the forge's own API/CLI instead","Contribute or upvote an implementation for the missing forge in the ci.rs match"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Rust: gate on the supported forge set before calling\nconst CI_SUPPORTED_FORGES: &[ForgeName] =\n    &[ForgeName::GitHub, ForgeName::GitLab, ForgeName::Bitbucket];\nif !CI_SUPPORTED_FORGES.contains(&forge) {\n    // skip CI listing for this remote; render 'CI status not supported'\n}","typeGuard":"fn supports_ci_checks(forge: ForgeName) -> bool {\n    matches!(forge, ForgeName::GitHub | ForgeName::GitLab | ForgeName::Bitbucket)\n}","tryCatchPattern":"match list_ci_checks(&forge, owner, repo, reference) {\n    Err(err) if err.to_string().contains(\"is not implemented yet\") => {\n        // treat CI as unsupported for this forge and hide the panel\n    }\n    result => result,\n}","preventionTips":["Check the forge name against the supported set before invoking CI features","Design UIs so CI status is an optional panel, not a required result","Track upstream forge-support parity before promising Azure DevOps CI in your tooling"],"tags":["forge","ci-checks","azure-devops","not-implemented"],"backgroundTag":"unsupported-forge","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}