{"record":{"id":"f8db95d50935131d","repo":"GitoxideLabs/gitoxide","slug":"named-threads-with-small-stack-work-on-all-platfor","errorCode":null,"errorMessage":"named threads with small stack work on all platforms","messagePattern":"named threads with small stack work on all platforms","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-transport/src/client/blocking_io/file.rs","lineNumber":262,"sourceCode":"        .name(\"supervise ssh stderr\".into())\n        .stack_size(128 * 1024)\n        .spawn(move || -> std::io::Result<()> {\n            let mut process_stderr = std::io::stderr();\n            for line in std::io::BufReader::new(stderr).byte_lines() {\n                let line = line?;\n                match ssh_kind.line_to_err(line.into()) {\n                    Ok(err) => {\n                        send.send(err).ok();\n                    }\n                    Err(line) => {\n                        process_stderr.write_all(&line).ok();\n                        writeln!(&process_stderr).ok();\n                    }\n                }\n            }\n            Ok(())\n        })\n        .expect(\"named threads with small stack work on all platforms\");\n    ReadStdoutFailOnError { read: stdout, recv }\n}\n\nimpl client::blocking_io::Transport for SpawnProcessOnDemand {\n    fn handshake<'a>(\n        &mut self,\n        service: Service,\n        extra_parameters: &'a [(&'a str, Option<&'a str>)],\n    ) -> Result<SetServiceResponse<'_>, client::Error> {\n        let (cmd, ssh_kind, cmd_name) = self.prepare_command(service)?;\n        let envs = std::mem::take(&mut self.envs);\n        let into_std_command = |mut cmd: gix_command::Prepare| {\n            cmd.stdin = Stdio::piped();\n            cmd.stdout = Stdio::piped();\n\n            let mut cmd = std::process::Command::from(cmd);\n            for env_to_remove in ENV_VARS_TO_REMOVE {\n                cmd.env_remove(env_to_remove);","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-transport/src/client/blocking_io/file.rs#L244-L280","documentation":"Panic from `std::thread::Builder::spawn().expect(\"named threads with small stack work on all platforms\")` inside `supervise_stderr`, which launches a helper thread to forward a child process's stderr during a transport handshake. The expect asserts that spawning a small-stack named thread always succeeds; failure means the OS refused to create the thread (resource exhaustion or platform limitation).","triggerScenarios":"Calling a blocking transport `handshake` (spawning `git upload-pack`/`receive-pack` or an SSH command) when thread creation fails — e.g. hitting RLIMIT_NPROC/`ulimit -u`, out of memory, or a platform where the small stack size is rejected.","commonSituations":"Containers with very low thread/process limits, deeply recursive workloads exhausting threads, or unusual/embedded targets with restrictive pthread settings.","solutions":["Raise the thread/process limit (`ulimit -u`) or container PID limit and retry.","Free resources (reduce concurrent connections) before retrying the fetch/push.","If on an exotic platform, run the blocking transport on a default-size stack, or use the async transport instead.","Retry the operation once resources are available — it is transient."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if rlimit::getrlimit(rlimit::Resource::NPROC).map(|(_, hard)| hard == 0).unwrap_or(false) {\n    anyhow::bail!(\"thread/process limit too low for transport threads\");\n}","typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(AssertUnwindSafe(|| transport.handshake(version))) {\n    Ok(r) => r?,\n    Err(_) => { wait_for_resources(); anyhow::bail!(\"handshake thread spawn failed; retry after raising limits\"); }\n}","preventionTips":["Raise RLIMIT_NPROC / container PID limits in constrained environments","Limit concurrent fetch/push operations","On exotic targets, test thread spawning with small stacks early","Fall back to the async transport where thread spawning differs"],"tags":["rust","panic","threads","resource-exhaustion","process-spawn"],"backgroundTag":"thread-spawn-failed","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}