linera-io/linera-protocol · warning
cannot have both a json string and file
Error message
cannot have both a json string and file
What it means
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.
Source
Thrown at linera-service/src/cli/main.rs:146
attempt += 1;
match operation().await {
Ok(result) => return Ok(result),
Err(err) if attempt < max_retries && is_retryable_error(&err) => {
let backoff_ms = 100 * 2_u64.pow(attempt - 1);
warn!(
"Faucet operation failed with retryable error (attempt {}/{}): {:?}. Retrying after {}ms",
attempt, max_retries, err, backoff_ms
);
tokio::time::sleep(Duration::from_millis(backoff_ms)).await;
}
Err(err) => return Err(err),
}
}
}
fn read_json(string: Option<String>, path: Option<PathBuf>) -> anyhow::Result<Vec<u8>> {
let value = match (string, path) {
(Some(_), Some(_)) => bail!("cannot have both a json string and file"),
(Some(s), None) => serde_json::from_str(&s)?,
(None, Some(path)) => {
let s = fs_err::read_to_string(path)?;
serde_json::from_str(&s)?
}
(None, None) => Value::Null,
};
Ok(serde_json::to_vec(&value)?)
}
#[async_trait]
impl Runnable for Job {
type Output = anyhow::Result<()>;
async fn run<S>(self, storage: S) -> anyhow::Result<()>
where
S: Storage + Clone + Send + Sync + 'static,
{View on GitHub (pinned to 6c226ddcb3)
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.
Example fix
# before
$ linera ... --json-parameters '{"a":1}' --json-parameters-path params.json
Error: cannot have both a json string and file
# after
$ linera ... --json-parameters-path params.json
# or
$ linera ... --json-parameters '{"a":1}' Defensive patterns
Strategy: validation
Validate before calling
// In wrappers, enforce exclusivity before invoking the CLI:
if json_string.is_some() && json_path.is_some() {
anyhow::bail!("pass either the inline JSON or the file, not both");
} Try / catch
match read_json(string, path).await {
Ok(bytes) => bytes,
Err(e) if e.to_string().contains("cannot have both") => {
// user error: drop one input and re-run; no retry helps
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Review assembled command lines for leftover flags before running.
- Make scripts choose one source with if/else instead of forwarding both unconditionally.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cannot apply default storage because the feature 'rocksdb' w
- Wallet already exists: {}
- Keystore already exists: {}
- Cannot process inbox for follow-only chain {chain_id}. Use `
- please specify one of `--faucet` or `--genesis`.
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/290ca7b8fb6a4910.
Report an issue: GitHub.