{"record":{"id":"f7010fbe90fa7a4e","repo":"AprilNEA/OpenLogi","slug":"id-and-name-must-match-the-in-progress-contribution","errorCode":null,"errorMessage":"--id and --name must match the in-progress contribution","messagePattern":"--id and --name must match the in-progress contribution","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/fixture/contribute.rs","lineNumber":472,"sourceCode":"    }\n    if args.name.trim().is_empty() {\n        bail!(\"--name must be a nonempty synthetic device name\");\n    }\n    if args.output.file_name() != Some(OsStr::new(&args.id)) {\n        bail!(\"--output directory name must exactly equal --id\");\n    }\n    Ok(())\n}\n\nfn validate_state(args: &ContributeArgs, state: &ContributionState) -> Result<()> {\n    if state.version != STATE_VERSION {\n        bail!(\"unsupported contribution state version {}\", state.version);\n    }\n    if state.fixture_id != args.id\n        || state.profile_id != format!(\"{}-profile\", args.id)\n        || state.profile_name != args.name\n    {\n        bail!(\"--id and --name must match the in-progress contribution\");\n    }\n    Ok(())\n}\n\nfn read_json<T: serde::de::DeserializeOwned>(path: &Path, asset: &str) -> Result<T> {\n    let bytes = fs::read(path).with_context(|| format!(\"could not read {asset}\"))?;\n    serde_json::from_slice(&bytes).with_context(|| format!(\"could not parse {asset}\"))\n}\n\nfn require_directory(path: &Path, asset: &str) -> Result<()> {\n    let metadata =\n        fs::symlink_metadata(path).with_context(|| format!(\"could not inspect {asset}\"))?;\n    if metadata.file_type().is_symlink() || !metadata.is_dir() {\n        bail!(\"{asset} must be a non-symlink directory\");\n    }\n    Ok(())\n}\n","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/fixture/contribute.rs#L454-L490","documentation":"The `finish` step verifies that `--id`/`--name` on the command line match the fixture id, profile id (`{id}-profile`), and profile name recorded in the in-progress contribution state. A mismatch means you are trying to finish a different (or renamed) contribution than the one whose state exists. `validate_state` rejects it.","triggerScenarios":"Run finish with an `--id` different from the one used at contribution start, or a `--name` that was changed since start; the state stores `profile_id = \"{id}-profile\"` and `profile_name = name`, and any divergence bails.","commonSituations":"Renaming a device between start and finish; finishing several contributions in a loop but passing the same id each time; typos in the id.","solutions":["Re-run finish with the exact same `--id` and `--name` used when the contribution was started.","If you intentionally renamed the device, discard the old state (remove the output dir) and start a fresh contribution with the new name.","Check the state file's `fixture_id`/`profile_name` fields to confirm the original values before re-running."],"exampleFix":"// before\nopenlogi fixture contribute finish --id mx-master --name \"MX Master 3S\" ...\n// after (state was started with the old name)\nopenlogi fixture contribute finish --id mx-master --name \"MX Master\" ...","handlingStrategy":"validation","validationCode":"stored=$(python3 -c \"import json;s=json.load(open('out/$ID/state.json'));print(s['fixture_id'], s['profile_name'])\")\n[ \"$stored\" = \"$ID $NAME\" ] || { echo \"--id/--name do not match in-progress contribution: $stored\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Record the original --id/--name at contribution start and reuse them verbatim at finish.","To rename a device, restart the contribution instead of renaming mid-flight.","Read the state file to confirm expected values before finishing."],"tags":["cli","validation","state-mismatch"],"backgroundTag":"invalid-state-transition","analyzedSha":"e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8","analyzedAt":"2026-09-13T03:07:16.451Z","contentChangedAt":"2026-09-13T03:07:16.451Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}