CLI: replace Rust Debug ({:#?}) output with JSON in three commands
#5979 opened on Apr 10, 2026
Description
Parent: linera-io/linera-protocol#5977 (Tier 1 item 3)
Problem
Three CLI commands print Rust Debug format output, which:
- Uses Rust struct syntax (
Foo { field: "value" }), not a standard data format. - Is inconsistent with the rest of the CLI, which uses
Displayorserde_json::to_string_pretty. - Is harder for scripts and agents to parse reliably than JSON or plain text.
- Changes shape across Rust versions (not technically stable).
Affected lines
All in linera-service/src/cli/main.rs:
- Line 1393 —
ListEventsFromIndex:println!("{:#?}", index_events); - Line 1751 —
Chain(ChainCommand::ShowBlock { .. }):println!("{:#?}", block); - Line 1768 —
Chain(ChainCommand::ShowChainDescription { .. }):println!("{:#?}", description);
Proposed fix
Replace with serde_json::to_string_pretty. Both underlying types already derive Serialize:
ConfirmedBlockatlinera-chain/src/block.rs:80(#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Allocative)])ChainDescriptionatlinera-base/src/data_types.rs:890(#[derive(Eq, PartialEq, Clone, Hash, Debug, Serialize, Deserialize, Allocative)])- The event list (
Vec<IndexAndEvent>or similar) also serializes — confirm by inspection.
Replacement pattern (apply to all three lines):
println!("{}", serde_json::to_string_pretty(&block)?);
Reference: main.rs:309-310 and main.rs:395-396 already use this exact pattern for ShowOwnership and ShowNetworkDescription.
Backwards compatibility
This is a user-visible output format change. Downstream scripts parsing the Debug format will break. Given:
- The Debug format is not a documented stable interface.
- Only three commands are affected, all of them "show" / "list" commands (read-only inspection).
- JSON is strictly easier to parse than Debug format.
…this is an acceptable change. No flag gating is needed. Mention it in the PR description and in any release notes.
Testing
No dedicated unit tests exist for these three commands today (verify with grep -n 'show-block\|show-chain-description\|list-events-from-index' linera-service/tests/). At minimum:
- Manual verification for each command: build, run it against a local network, confirm the output is valid JSON (
| jq .). - Optionally add a minimal E2E test in
linera-service/tests/linera_net_tests.rsthat runs each command viaClientWrapperand asserts the stdout parses as JSON.
Manual verification:
cargo build -p linera-service --bin linera
./target/debug/linera net up --with-faucet --faucet-port 8080
# In another terminal, with env vars exported:
./target/debug/linera chain show-block <some-block-hash> | jq .
./target/debug/linera chain show-chain-description | jq .
./target/debug/linera list-events-from-index --stream-id <id> | jq .
Definition of done
- Three
println!("{:#?}", ...)calls replaced withserde_json::to_string_pretty. - Output verified as valid JSON via
jq .. -
cargo clippy --all-targets --all-features -- -D warningspasses. -
cargo fmtapplied. - PR description mentions the user-visible output format change.
Good first issue
This is a ~5-line change across one file with minimal risk. Good candidate for a newcomer. No design discussion required — just open a PR.