{"record":{"id":"f1e1334fff9a5892","repo":"linera-io/linera-protocol","slug":"unable-to-open-committee-configuration","errorCode":null,"errorMessage":"Unable to open committee configuration","messagePattern":"Unable to open committee configuration","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-service/src/server.rs","lineNumber":919,"sourceCode":"                    .expect(\"Unable to open server config file\");\n                Persist::persist(&mut server)\n                    .await\n                    .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)","sourceCodeStart":901,"sourceCodeEnd":937,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-service/src/server.rs#L901-L937","documentation":"Panic when `persistent::File::new(&committee, CommitteeConfig{...})` fails for the `--committee <path>` argument of `server generate`. `File::new` opens/creates the committee file (0600 on Unix), takes a non-blocking exclusive flock, and performs an initial atomic save of the JSON committee description. The 'open' message therefore also covers lock contention and initial-save I/O errors.","triggerScenarios":"`--committee committee.json` where the parent directory does not exist or is unwritable; another linera process holds the committee file locked; the initial save fails on a read-only filesystem or ENOSPC; a stale `committee.json.new` blocks creation of the staging file.","commonSituations":"Committee path given as a bare filename while the cwd is not writable; /etc/linera not created in a fresh install; running generate with --committee while other linera tooling reads the same file; config volumes mounted read-only under orchestration.","solutions":["`mkdir -p` the committee file's directory and make it writable by the current user.","Ensure no other linera process holds the committee file; stop it or rerun later.","Remove stale `committee.json.new` staging leftovers.","Check disk space (`df -h`) and that the mount is read-write.","Handle the Result with context instead of expect in custom code."],"exampleFix":"// before\nlet mut config = persistent::File::new(\n    &committee,\n    CommitteeConfig { validators: config_validators },\n)\n.expect(\"Unable to open committee configuration\");\n// after\nif let Some(parent) = committee.parent().filter(|p| !p.as_os_str().is_empty()) {\n    std::fs::create_dir_all(parent)?;\n}\nlet mut config = persistent::File::new(\n    &committee,\n    CommitteeConfig { validators: config_validators },\n)\n.with_context(|| format!(\"unable to create committee file {}\", committee.display()))?;","handlingStrategy":"validation","validationCode":"if let Some(parent) = committee.parent().filter(|p| !p.as_os_str().is_empty()) {\n    std::fs::create_dir_all(parent)\n        .with_context(|| format!(\"committee dir missing: {}\", parent.display()))?;\n}\nlet probe = committee.with_extension(\"probe\");\nstd::fs::write(&probe, b\"\")?;\nstd::fs::remove_file(&probe)?;","typeGuard":null,"tryCatchPattern":"let mut config = match persistent::File::new(&committee, CommitteeConfig { validators: config_validators }) {\n    Ok(config) => config,\n    Err(err) => {\n        eprintln!(\"error: unable to open committee configuration {}: {err}\", committee.display());\n        std::process::exit(1);\n    }\n};","preventionTips":["Pre-create the committee directory in deployment tooling before invoking generate with --committee.","Use absolute paths for the committee file to avoid cwd surprises.","Keep a single writer at a time for the committee file; the exclusive flock is non-blocking.","Ensure the config volume is writable and has free space before running generate."],"tags":["rust","file-io","permissions","file-lock","committee"],"backgroundTag":"file-permission-denied","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}