{"record":{"id":"1ce012f4da3ed9bc","repo":"gitbutlerapp/gitbutler","slug":"failed-to-create-tokio-runtime-err","errorCode":null,"errorMessage":"Failed to create tokio runtime: {err}","messagePattern":"Failed to create tokio runtime: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-forge/src/ci.rs","lineNumber":145,"sourceCode":"                        })\n                        .collect()\n                })\n            })\n        }\n        ForgeName::GitLab => {\n            let preferred_account = preferred_forge_user\n                .as_ref()\n                .and_then(|user| user.gitlab().cloned());\n            let gl = but_gitlab::GitLabClient::from_storage(storage, preferred_account.as_ref())?;\n\n            // Clone owned data for thread\n            let project_id = but_gitlab::GitLabProjectId::new(owner, repo);\n            let reference = reference.to_string();\n            let reference_for_checks = reference.clone();\n\n            let pipelines = std::thread::spawn(move || -> anyhow::Result<_> {\n                let runtime = tokio::runtime::Runtime::new()\n                    .map_err(|err| anyhow::anyhow!(\"Failed to create tokio runtime: {err}\"))?;\n                runtime.block_on(gl.list_pipeline_jobs_for_ref(project_id, &reference))\n            })\n            .join()\n            .map_err(|e| anyhow::anyhow!(\"Failed to join thread: {e:?}\"))??;\n            Ok(Some(\n                pipelines\n                    .into_iter()\n                    .map(|pipeline| {\n                        let mut ci_check = CiCheck::from(pipeline);\n                        ci_check.reference = reference_for_checks.to_string();\n                        ci_check\n                    })\n                    .collect(),\n            ))\n        }\n        ForgeName::Bitbucket => {\n            let preferred_account = preferred_forge_user\n                .as_ref()","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-forge/src/ci.rs#L127-L163","documentation":"For GitLab pipelines, but-forge spawns a thread and creates a fresh tokio runtime to run the async API call (list_pipeline_jobs_for_ref) synchronously. Runtime::new() returned Err - the process could not allocate what a runtime needs (worker threads, I/O driver, memory). The error text carries the underlying io::Error.","triggerScenarios":"Calling CI listing for a GitLab remote when the process cannot create another runtime: thread or file-descriptor limits exhausted, or severe memory pressure.","commonSituations":"Desktop app sandboxes and CI containers with restrictive ulimits; many forge requests racing so each spawns its own runtime and the limit is hit.","solutions":["Raise limits for the process: `ulimit -n` (file descriptors) and thread limits, or adjust the sandbox profile","Reduce concurrent CI lookups so fewer runtimes exist at once","If persistent, report upstream - the long-term fix is a single shared runtime instead of per-call runtimes"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match list_ci_checks(&forge, owner, repo, reference) {\n    Err(err) if err.to_string().contains(\"Failed to create tokio runtime\") => {\n        // degrade to 'CI checks unavailable'; suggest checking resource limits\n    }\n    result => result,\n}","preventionTips":["Raise file-descriptor and thread limits for the app process (ulimit -n, sandbox profile)","Serialize or throttle forge calls so runtime creation pressure stays low","Track this as an upstream issue: per-call runtimes should be a single shared runtime"],"tags":["gitlab","tokio","runtime","ci-checks"],"backgroundTag":"tokio-runtime-creation-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}