linera-io/linera-protocol · error
{}: got non-zero error code {}
Error message
{}: got non-zero error code {} What it means
CommandExt::spawn_and_wait_for_stdout pipes stdout, inherits stderr, spawns the child process, and after wait_with_output checks output.status.success(). A non-zero exit code (including death by signal, reported as exit code 128+N on Unix) fails the ensure!, prefixed with 'While executing {:?}' describing the command. The child's own diagnostics went to inherited stderr, so the reason is visible in the surrounding log, not in this error.
Source
Thrown at linera-base/src/command.rs:164
fn spawn_into(&mut self) -> anyhow::Result<tokio::process::Child> {
self.kill_on_drop(true);
debug!("Spawning {:?}", self);
let child = tokio::process::Command::spawn(self).with_context(|| self.description())?;
Ok(child)
}
async fn spawn_and_wait_for_stdout(&mut self) -> anyhow::Result<String> {
debug!("Spawning and waiting for {:?}", self);
self.stdout(Stdio::piped());
self.stderr(Stdio::inherit());
self.kill_on_drop(true);
let child = self.spawn().with_context(|| self.description())?;
let output = child
.wait_with_output()
.await
.with_context(|| self.description())?;
ensure!(
output.status.success(),
"{}: got non-zero error code {}",
self.description(),
output.status,
);
String::from_utf8(output.stdout).with_context(|| self.description())
}
async fn spawn_and_wait(&mut self) -> anyhow::Result<()> {
debug!("Spawning and waiting for {:?}", self);
self.kill_on_drop(true);
let mut child = self.spawn().with_context(|| self.description())?;
let status = child.wait().await.with_context(|| self.description())?;
ensure!(
status.success(),
"{}: got non-zero error code {}",
self.description(),View on GitHub (pinned to 6c226ddcb3)
Solutions
- Read the child's stderr directly above this error in the log — it contains the actual failure cause
- Re-run the failing subcommand manually with the same arguments to reproduce (the {:?} command description in the message shows program and args)
- For test-harness failures, clean stale state: kill leftover processes and remove the temporary DB/wallet dirs
- If the binary panicked, rebuild (cargo build) and confirm versions match between spawner and child
Example fix
// before
let stdout = cmd.spawn_and_wait_for_stdout().await?; // exit code 1, cause hidden
// after (capture stderr so the cause travels with the error)
let out = cmd.output().await?;
if !out.status.success() {
anyhow::bail!(
"command failed ({}): {}",
out.status,
String::from_utf8_lossy(&out.stderr)
);
} Defensive patterns
Strategy: try-catch
Try / catch
match cmd.spawn_and_wait_for_stdout().await {
Ok(stdout) => stdout,
Err(e) => {
let msg = e.to_string();
if msg.contains("non-zero error code") {
// child diagnostics are on inherited stderr just above; surface command context
tracing::error!("child failed: {msg}");
}
return Err(e);
}
} Prevention
- Run spawned helper binaries manually with the same args when tests fail — the {:?} in the message shows them
- Clean up ports and temp state between test runs so children don't fail on bind conflicts
- Keep spawner and child binaries built from the same commit
When it happens
Trigger: Any spawned helper binary exiting non-zero: linera-spawn during fungible benchmark setup, linera generate-initial-validator-config, storage initialization (initialize_storage), validator config generation, or linera project new/publish failing validation.
Common situations: Port already in use by a previous test run; missing tokio/rocksdb/dynamodb dependency or bad --storage URL; project publish with an invalid linera.toml; the spawned linera binary built from stale code that panicked; PATH resolving to an old binary.
Related errors
- Child process {self:?} already exited with status: {status}
- Expected an `ExecutionError`. Got: {self:#?}
- Expected an `ExecutionError`. Got: {chain_error:#?}
- Failed to obtain a port
- Chain listener exited unexpectedly: {result:?}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/27e5d4c6740c1680.
Report an issue: GitHub.