linera-io/linera-protocol · error

Unable to write committee description

Error message

Unable to write committee description

What it means

Panic when `Persist::persist(&mut config)` fails after the committee file was created in `server generate`. The CommitteeConfig is serialized as pretty JSON to `committee.json.new` and atomically renamed over the target; failure is an I/O error on staging create/write/flush/rename or, rarely, a serialization error. Because of the staging-rename design, a previously existing committee file is left untouched when this panic fires.

Source

Thrown at linera-service/src/server.rs:922

                    .expect("Unable to write server config file");
                info!("Wrote server config {}", path.to_str().unwrap());
                println!(
                    "{},{}",
                    server.validator.public_key, server.validator.account_key
                );
                config_validators.push(Persist::into_value(server).validator);
            }
            if let Some(committee) = committee {
                let mut config = persistent::File::new(
                    &committee,
                    CommitteeConfig {
                        validators: config_validators,
                    },
                )
                .expect("Unable to open committee configuration");
                Persist::persist(&mut config)
                    .await
                    .expect("Unable to write committee description");
                info!("Wrote committee config {}", committee.to_str().unwrap());
            }
        }

        ServerCommand::EditShards {
            server_config_path,
            num_shards,
            host,
            port,
            metrics_port,
        } => {
            let mut server_config =
                persistent::File::<ValidatorServerConfig>::read(&server_config_path)
                    .expect("Failed to read server config");
            let shards = generate_shard_configs(&num_shards, &host, &port, &metrics_port)
                .expect("Failed to generate shard configs");
            server_config.internal_network.shards = shards;
            Persist::persist(&mut server_config)

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Free space or enlarge the volume (`df -h <dir>`).
  2. Make the committee directory writable by the running user (chown/chmod, rw mount).
  3. Remove stale `committee.json.new` files.
  4. Propagate the error instead of expect in custom builds to capture the exact errno.

Example fix

// before
Persist::persist(&mut config)
    .await
    .expect("Unable to write committee description");
// after
Persist::persist(&mut config)
    .await
    .with_context(|| format!("unable to write committee file {}", committee.display()))?;
Defensive patterns

Strategy: validation

Validate before calling

let dir = committee.parent().unwrap_or(Path::new("."));
anyhow::ensure!(!fs_err::metadata(dir)?.permissions().readonly(), "committee dir is read-only: {}", dir.display());
let mut staging = committee.clone();
staging.set_extension("json.new");
if staging.exists() {
    fs_err::remove_file(&staging)?;
}

Try / catch

if let Err(err) = Persist::persist(&mut config).await {
    eprintln!("error: unable to write committee description {}: {err}", committee.display());
    std::process::exit(1);
}

Prevention

When it happens

Trigger: ENOSPC while flushing the staging file; EACCES/EROFS creating `committee.json.new` in a read-only or root-owned directory; rename failing on exotic filesystems; leftover staging file that the current user cannot write or replace.

Common situations: Full disks on testnet machines; config directories on read-only mounts; mixed root/non-root container runs leaving root-owned files; large validator sets filling the last bits of a small volume.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/960ac06b726c07b5. Report an issue: GitHub.