{"record":{"id":"f483e23455039317","repo":"linera-io/linera-protocol","slug":"unable-to-read-validator-options-file","errorCode":null,"errorMessage":"Unable to read validator options file","messagePattern":"Unable to read validator options file","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-service/src/server.rs","lineNumber":896,"sourceCode":"            store_config\n                .run_with_storage(wasm_runtime, allow_application_logs, cache_sizes, job)\n                .boxed()\n                .await\n                .unwrap()\n                .unwrap();\n        }\n\n        ServerCommand::Generate {\n            validators,\n            committee,\n            testing_prng_seed,\n        } => {\n            let mut config_validators = Vec::new();\n            let mut rng = Box::<dyn CryptoRng>::from(testing_prng_seed);\n            for options_path in validators {\n                let options_string = fs_err::tokio::read_to_string(options_path)\n                    .await\n                    .expect(\"Unable to read validator options file\");\n                let options: ValidatorOptions = toml::from_str(&options_string)\n                    .unwrap_or_else(|_| panic!(\"Invalid options file format: \\n {options_string}\"));\n                let path = options.server_config_path.clone();\n                let mut server = make_server_config(&path, &mut rng, options)\n                    .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,","sourceCodeStart":878,"sourceCodeEnd":914,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-service/src/server.rs#L878-L914","documentation":"Panic raised by `linera-service server generate` when `fs_err::tokio::read_to_string` fails on one of the files passed via `--validators <path>`. The file must exist, be readable by the current user, and contain valid UTF-8, because it is immediately parsed as TOML into ValidatorOptions. Since `.expect()` is used, the whole CLI command aborts with this message plus the underlying std::io::Error (fs_err decorates it with the failing path).","triggerScenarios":"Running `linera-service server generate --validators <path> ...` where the path does not exist, is a directory, has no read permission, or contains non-UTF-8 bytes; also when a relative path is resolved against a different working directory than the one assumed.","commonSituations":"Typo'd or relative --validators path used from the wrong cwd; options file copied from another machine/user without read permission; container running as non-root against a root-owned file; provisioning scripts referencing a temp options file that was already cleaned up.","solutions":["Verify the file exists and is readable (`ls -l <path>`, `cat <path>`) and contains readable TOML text.","Pass an absolute path, or re-run the command from the directory the relative path is based on.","Fix permissions or ownership: `chmod +r <file>` / `chown $(id -un) <file>`, and confirm the container user can read it.","If embedding this code path, replace `.expect(...)` with `.with_context(...)?` so the decorated io::Error is reported instead of a panic."],"exampleFix":"// before\nlet options_string = fs_err::tokio::read_to_string(options_path)\n    .await\n    .expect(\"Unable to read validator options file\");\n// after\nlet options_string = fs_err::tokio::read_to_string(&options_path)\n    .await\n    .with_context(|| format!(\"unable to read validator options file: {}\", options_path.display()))?;","handlingStrategy":"validation","validationCode":"let meta = fs_err::metadata(&options_path)\n    .with_context(|| format!(\"validator options file not found: {}\", options_path.display()))?;\nanyhow::ensure!(meta.is_file(), \"not a regular file: {}\", options_path.display());\nlet bytes = fs_err::read(&options_path)?;\nanyhow::ensure!(std::str::from_utf8(&bytes).is_ok(), \"validator options file is not valid UTF-8\");","typeGuard":null,"tryCatchPattern":"let options_string = match fs_err::tokio::read_to_string(&options_path).await {\n    Ok(s) => s,\n    Err(err) => {\n        eprintln!(\"error: unable to read validator options file: {err}\");\n        std::process::exit(1);\n    }\n};","preventionTips":["Always pass --validators an absolute path, or resolve it against a documented working directory in scripts.","Check the file with `cat`/`file` before invoking generate; it must be readable UTF-8 TOML.","In deployment manifests, ensure the process user owns or can read the options files.","Regenerate the options file from the provisioning template whenever this panic appears, instead of retrying blindly."],"tags":["rust","file-io","config","toml","cli"],"backgroundTag":"file-not-found","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}