{"record":{"id":"f08f15d67f81244c","repo":"astrid-runtime/astrid","slug":"git-history-requires-non-empty-name-repo-relati","errorCode":null,"errorMessage":"--git-history requires non-empty NAME=REPO::RELATIVE_PATH","messagePattern":"--git-history requires non-empty NAME=REPO::RELATIVE_PATH","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-chunker-evidence/src/main.rs","lineNumber":209,"sourceCode":"    Ok(Options {\n        corpus_specs,\n        version_chain_specs,\n        git_history_specs,\n        include_synthetic,\n        sketch_only,\n        targets_kib,\n        output,\n    })\n}\n\nfn parse_git_specification(specification: Option<String>) -> Result<(String, PathBuf, PathBuf)> {\n    let (name, combined) = parse_path_specification(\"--git-history\", specification)?;\n    let combined = combined.to_string_lossy();\n    let (repository, relative_path) = combined\n        .split_once(\"::\")\n        .ok_or_else(|| anyhow::anyhow!(\"--git-history requires NAME=REPO::RELATIVE_PATH\"))?;\n    if repository.is_empty() || relative_path.is_empty() {\n        bail!(\"--git-history requires non-empty NAME=REPO::RELATIVE_PATH\");\n    }\n    Ok((\n        name,\n        PathBuf::from(repository),\n        PathBuf::from(relative_path),\n    ))\n}\n\nfn parse_path_specification(\n    flag: &str,\n    specification: Option<String>,\n) -> Result<(String, PathBuf)> {\n    let specification =\n        specification.ok_or_else(|| anyhow::anyhow!(\"{flag} requires NAME=PATH\"))?;\n    let (name, path) = specification\n        .split_once('=')\n        .ok_or_else(|| anyhow::anyhow!(\"{flag} requires NAME=PATH\"))?;\n    if name.is_empty() || path.is_empty() {","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-chunker-evidence/src/main.rs#L191-L227","documentation":"`parse_git_specification` splits the value after `NAME=PATH` on `::` into repository and relative path, and bails when either side is empty. A git-history corpus must name both a repository directory and an in-repo path.","triggerScenarios":"Passing `--git-history name=repo::` (empty relative path), `--git-history name=::path` (empty repo), or in `parse_path_specification` a value missing `NAME=PATH` structure entirely.","commonSituations":"Truncated shell variables (`REPO::` with unset path), copy-paste losing characters, Windows drive letters being mistaken as separators, or scripts joining paths incorrectly.","solutions":["Supply both parts in full: `--git-history samples=/path/to/repo::relative/file.bin`","Check the shell variable holding the path isn't empty (`echo \"$SPEC\"`) before invoking","Use a relative in-repo path for the part after `::`"],"exampleFix":"// before\nSPEC=\"samples=/srv/repo::\"; bin --git-history \"$SPEC\"\n// after\nSPEC=\"samples=/srv/repo::bench/corpus/sample.bin\"; bin --git-history \"$SPEC\"","handlingStrategy":"validation","validationCode":"fn valid_git_spec(spec: &str) -> bool {\n    let (name, rest) = match spec.split_once('=') { Some(x) => x, None => return false };\n    let (repo, rel) = match rest.split_once(\"::\") { Some(x) => x, None => return false };\n    !name.is_empty() && !repo.is_empty() && !rel.is_empty()\n}\nassert!(valid_git_spec(&spec), \"malformed --git-history spec: {spec}\");","typeGuard":null,"tryCatchPattern":"match run_cli(args) {\n    Err(e) if e.to_string().contains(\"NAME=REPO::RELATIVE_PATH\") => {\n        eprintln!(\"{e}; quoting spec: --git-history 'samples=/repo::path/file.bin'\");\n        std::process::exit(2);\n    }\n    other => other,\n}","preventionTips":["Quote `--git-history` values in shell so `=` and `::` survive intact","Validate the NAME=REPO::PATH shape in scripts before exec","Echo interpolated shell variables to confirm none are empty before building the spec"],"tags":["rust","cli","argument-format","git","configuration"],"backgroundTag":"invalid-argument-format","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}