{"record":{"id":"960ac06b726c07b5","repo":"linera-io/linera-protocol","slug":"unable-to-write-committee-description","errorCode":null,"errorMessage":"Unable to write committee description","messagePattern":"Unable to write committee description","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-service/src/server.rs","lineNumber":922,"sourceCode":"                    .expect(\"Unable to write server config file\");\n                info!(\"Wrote server config {}\", path.to_str().unwrap());\n                println!(\n                    \"{},{}\",\n                    server.validator.public_key, server.validator.account_key\n                );\n                config_validators.push(Persist::into_value(server).validator);\n            }\n            if let Some(committee) = committee {\n                let mut config = persistent::File::new(\n                    &committee,\n                    CommitteeConfig {\n                        validators: config_validators,\n                    },\n                )\n                .expect(\"Unable to open committee configuration\");\n                Persist::persist(&mut config)\n                    .await\n                    .expect(\"Unable to write committee description\");\n                info!(\"Wrote committee config {}\", committee.to_str().unwrap());\n            }\n        }\n\n        ServerCommand::EditShards {\n            server_config_path,\n            num_shards,\n            host,\n            port,\n            metrics_port,\n        } => {\n            let mut server_config =\n                persistent::File::<ValidatorServerConfig>::read(&server_config_path)\n                    .expect(\"Failed to read server config\");\n            let shards = generate_shard_configs(&num_shards, &host, &port, &metrics_port)\n                .expect(\"Failed to generate shard configs\");\n            server_config.internal_network.shards = shards;\n            Persist::persist(&mut server_config)","sourceCodeStart":904,"sourceCodeEnd":940,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-service/src/server.rs#L904-L940","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Free space or enlarge the volume (`df -h <dir>`).","Make the committee directory writable by the running user (chown/chmod, rw mount).","Remove stale `committee.json.new` files.","Propagate the error instead of expect in custom builds to capture the exact errno."],"exampleFix":"// before\nPersist::persist(&mut config)\n    .await\n    .expect(\"Unable to write committee description\");\n// after\nPersist::persist(&mut config)\n    .await\n    .with_context(|| format!(\"unable to write committee file {}\", committee.display()))?;","handlingStrategy":"validation","validationCode":"let dir = committee.parent().unwrap_or(Path::new(\".\"));\nanyhow::ensure!(!fs_err::metadata(dir)?.permissions().readonly(), \"committee dir is read-only: {}\", dir.display());\nlet mut staging = committee.clone();\nstaging.set_extension(\"json.new\");\nif staging.exists() {\n    fs_err::remove_file(&staging)?;\n}","typeGuard":null,"tryCatchPattern":"if let Err(err) = Persist::persist(&mut config).await {\n    eprintln!(\"error: unable to write committee description {}: {err}\", committee.display());\n    std::process::exit(1);\n}","preventionTips":["Check `df -h` on the config volume before generating committees on shared test machines.","Clean `committee.json.new` leftovers between runs in scripted environments.","Run all config-writing commands as the same user to keep 0600 staging files writable.","Remember the previous committee file survives a failed persist (atomic rename), so a retry after fixing the environment is safe."],"tags":["rust","file-io","disk-full","atomic-write","committee"],"backgroundTag":"file-write-failed","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}