{"record":{"id":"5ce03dc451ad07d7","repo":"tauri-apps/tauri","slug":"failed-to-parse-capabilities","errorCode":null,"errorMessage":"failed to parse capabilities","messagePattern":"failed to parse capabilities","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-codegen/src/context.rs","lineNumber":406,"sourceCode":"        crypto_keys: std::boxed::Box::new(::tauri::utils::pattern::isolation::Keys::new().expect(\"unable to generate cryptographically secure keys for Tauri \\\"Isolation\\\" Pattern\")),\n      })\n    }\n  };\n\n  let acl_file_path = out_dir.join(ACL_MANIFESTS_FILE_NAME);\n  let acl: BTreeMap<String, Manifest> = if acl_file_path.exists() {\n    let acl_file =\n      std::fs::read_to_string(acl_file_path).expect(\"failed to read plugin manifest map\");\n    serde_json::from_str(&acl_file).expect(\"failed to parse plugin manifest map\")\n  } else {\n    Default::default()\n  };\n\n  let capabilities_file_path = out_dir.join(CAPABILITIES_FILE_NAME);\n  let capabilities_from_files = if capabilities_file_path.exists() {\n    let capabilities_json =\n      std::fs::read_to_string(&capabilities_file_path).expect(\"failed to read capabilities\");\n    serde_json::from_str(&capabilities_json).expect(\"failed to parse capabilities\")\n  } else {\n    Default::default()\n  };\n  let capabilities = get_capabilities(\n    &config,\n    capabilities_from_files,\n    additional_capabilities.as_deref(),\n  )\n  .unwrap();\n\n  let resolved = Resolved::resolve(&acl, capabilities, target).expect(\"failed to resolve ACL\");\n\n  let acl_tokens = map_lit(\n    quote! { ::std::collections::BTreeMap },\n    &acl,\n    str_lit,\n    identity,\n  );","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-codegen/src/context.rs#L388-L424","documentation":"Build-time panic in tauri-codegen: serde_json::from_str over OUT_DIR/capabilities.json .expect(\"failed to parse capabilities\") fails when the cached capabilities file is invalid JSON or no longer matches the structure the current tauri-codegen expects. The cache is produced by tauri-build from src-tauri/capabilities/*; a mismatch means a corrupt/truncated artifact or a version skew between writer and reader.","triggerScenarios":"Building after a Tauri upgrade with a stale capabilities.json in OUT_DIR; a build interrupted while writing the file; mixed tauri crate versions in one workspace producing schema drift.","commonSituations":"Tauri minor upgrade without cleaning target; CI cache reuse of target across version bumps; editing capabilities while a build runs, leaving a torn cache.","solutions":["cargo clean and rebuild","Align Tauri crate versions: `cargo tree -i tauri-utils` / `cargo tree -i tauri-build`, fix duplicates","Add/modify capability files only while no build is running, then rebuild","Clear CI build caches keyed on Cargo.lock after any Tauri dependency change"],"exampleFix":"# before: panic: failed to parse capabilities\n\n# after\ncargo clean && cargo build","handlingStrategy":"validation","validationCode":"# validate the capability cache parses before the codegen step runs\npython3 -c \"import json;json.load(open('target/debug/build'))\" 2>/dev/null || cargo clean","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clean the target directory after Tauri upgrades","Verify a single tauri-utils version in the dependency graph (cargo tree -i tauri-utils)","Never hand-edit generated files under target/"],"tags":["acl","capabilities","json","build"],"backgroundTag":"stale-build-artifact","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}