ccusage/ccusage · critical
parse CLI help spec
Error message
parse CLI help spec
What it means
generate_cli_help_rs parses the CLI help JSON with serde_json::from_str::<Value> and unwraps with expect("parse CLI help spec"). If cli-help.json (the option_source file) contains invalid JSON or a structure that cannot deserialize as serde_json::Value (practically: any malformed JSON), the build script panics with 'parse CLI help spec' and the crate fails to compile. This is the parse step for the options spec, distinct from error [3] which is the read of the commands spec.
Source
Thrown at rust/crates/ccusage-cli-parser/build.rs:24
mod help_codegen;
const CLI_HELP_JSON: &str = "src/cli-help.json";
const CLI_COMMANDS_JSON: &str = "src/cli-commands.json";
fn main() {
println!("cargo:rerun-if-changed={CLI_HELP_JSON}");
println!("cargo:rerun-if-changed={CLI_COMMANDS_JSON}");
generate_cli_help_rs();
}
fn out_dir_path(file_name: &str) -> PathBuf {
PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR is set by cargo")).join(file_name)
}
fn generate_cli_help_rs() {
let option_source = fs::read_to_string(CLI_HELP_JSON).expect("read CLI help spec");
let command_source = fs::read_to_string(CLI_COMMANDS_JSON).expect("read CLI command spec");
let option_sets = serde_json::from_str::<Value>(&option_source).expect("parse CLI help spec");
let command_spec =
serde_json::from_str::<Value>(&command_source).expect("parse CLI command spec");
let output = help_codegen::generate_cli_help_source(&option_sets, &command_spec);
fs::write(out_dir_path("cli-help.rs"), output).expect("write generated CLI help");
}
View on GitHub (pinned to afebc5d2e0)
Solutions
- Validate the CLI help JSON with a linter (jq . cli-help.json or any JSON validator) to find the exact syntax error and line.
- Fix the malformed JSON — common culprits are leftover git conflict markers, trailing commas, or a truncated file from a failed generation run.
- Regenerate the spec with its authoring/codegen script instead of editing it by hand.
- Re-encode the file as UTF-8 without BOM if an editor changed the encoding.
Example fix
// before (cli-help.json, bad merge resolution)
{
<<<<<<< HEAD
"verbose": {"short": "v"},
=======
"quiet": {"short": "q"}
>>>>>>> main
}
// after
{
"verbose": {"short": "v"},
"quiet": {"short": "q"}
} Defensive patterns
Strategy: validation
Validate before calling
// validate spec JSON before the build script consumes it
let option_source = fs::read_to_string(CLI_HELP_JSON).expect("read CLI help spec");
serde_json::from_str::<serde_json::Value>(&option_source)
.unwrap_or_else(|e| panic!("parse CLI help spec at {CLI_HELP_JSON}: {e}"));
// CI pre-flight:
// jq empty cli-help.json || { echo "invalid cli-help.json"; exit 1; } Prevention
- Run jq (or a JSON schema check) on spec files in CI before building.
- Regenerate specs with scripts rather than hand-editing them.
- Resolve merge conflicts in JSON specs by regenerating, never by hand-editing markers.
- Always save spec files as UTF-8 without BOM.
When it happens
Trigger: cargo build/check on ccusage-cli-parser when the CLI help JSON file contains a syntax error (trailing comma, unquoted key, truncated file from a failed write or bad merge conflict resolution), or the file is empty/encoded incorrectly (BOM, non-UTF8).
Common situations: A merge conflict in cli-help.json resolved by committing conflict markers (<<<<<<) into the JSON; a codegen script that wrote a partial file; editing the spec by hand and introducing a JSON syntax error; a non-UTF8 file saved by an editor.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- parse CLI command spec
- read CLI command spec
- compact LiteLLM pricing JSON
- pricing response failed {endpoint:?} validation
- write generated CLI help
AI-assisted analysis of ccusage/ccusage@afebc5d2e0 (2026-09-02).
Data as JSON: /api/errors/e0692f4534e35652.
Report an issue: GitHub.