{"record":{"id":"290ca7b8fb6a4910","repo":"linera-io/linera-protocol","slug":"cannot-have-both-a-json-string-and-file","errorCode":null,"errorMessage":"cannot have both a json string and file","messagePattern":"cannot have both a json string and file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"linera-service/src/cli/main.rs","lineNumber":146,"sourceCode":"        attempt += 1;\n        match operation().await {\n            Ok(result) => return Ok(result),\n            Err(err) if attempt < max_retries && is_retryable_error(&err) => {\n                let backoff_ms = 100 * 2_u64.pow(attempt - 1);\n                warn!(\n                    \"Faucet operation failed with retryable error (attempt {}/{}): {:?}. Retrying after {}ms\",\n                    attempt, max_retries, err, backoff_ms\n                );\n                tokio::time::sleep(Duration::from_millis(backoff_ms)).await;\n            }\n            Err(err) => return Err(err),\n        }\n    }\n}\n\nfn read_json(string: Option<String>, path: Option<PathBuf>) -> anyhow::Result<Vec<u8>> {\n    let value = match (string, path) {\n        (Some(_), Some(_)) => bail!(\"cannot have both a json string and file\"),\n        (Some(s), None) => serde_json::from_str(&s)?,\n        (None, Some(path)) => {\n            let s = fs_err::read_to_string(path)?;\n            serde_json::from_str(&s)?\n        }\n        (None, None) => Value::Null,\n    };\n    Ok(serde_json::to_vec(&value)?)\n}\n\n#[async_trait]\nimpl Runnable for Job {\n    type Output = anyhow::Result<()>;\n\n    async fn run<S>(self, storage: S) -> anyhow::Result<()>\n    where\n        S: Storage + Clone + Send + Sync + 'static,\n    {","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-service/src/cli/main.rs#L128-L164","documentation":"read_json() accepts a JSON value either as an inline string or as a file path, but not both. When both Some(string) and Some(path) are supplied, it immediately bails. This helper backs CLI options like --json-grammar-parameter / --parameters <json|file> style pairs, so passing an inline value and a file in the same invocation is rejected before parsing.","triggerScenarios":"Invoking a linera CLI command with both the inline JSON option and its file variant populated, e.g. --some-json '{\"a\":1}' --some-json-path file.json (per the command's declared options), or a wrapper script always forwarding both flags.","commonSituations":"Copy-pasted command lines where a previous flag was left in; scripts that unconditionally pass a default file plus a user-supplied string; shell aliases appending extra options.","solutions":["Remove one of the two inputs — keep either the inline JSON string or the file path, not both.","In wrapper scripts, make the flags mutually exclusive: only forward the file when no inline string is given.","If you meant to merge two JSON documents, merge them yourself first and pass a single source."],"exampleFix":"# before\n$ linera ... --json-parameters '{\"a\":1}' --json-parameters-path params.json\nError: cannot have both a json string and file\n\n# after\n$ linera ... --json-parameters-path params.json\n# or\n$ linera ... --json-parameters '{\"a\":1}'","handlingStrategy":"validation","validationCode":"// In wrappers, enforce exclusivity before invoking the CLI:\nif json_string.is_some() && json_path.is_some() {\n    anyhow::bail!(\"pass either the inline JSON or the file, not both\");\n}","typeGuard":null,"tryCatchPattern":"match read_json(string, path).await {\n    Ok(bytes) => bytes,\n    Err(e) if e.to_string().contains(\"cannot have both\") => {\n        // user error: drop one input and re-run; no retry helps\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Review assembled command lines for leftover flags before running.","Make scripts choose one source with if/else instead of forwarding both unconditionally."],"tags":["linera-service","cli","argument-validation","mutually-exclusive","rust"],"backgroundTag":"mutually-exclusive-arguments","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}