{"record":{"id":"924718e46f64238c","repo":"rtk-ai/rtk","slug":"validated-object","errorCode":null,"errorMessage":"validated object","messagePattern":"validated object","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/hooks/init.rs","lineNumber":5134,"sourceCode":"/// cannot cause a partially-applied update.\nfn patch_trae_hooks_json_paths(paths: &[PathBuf], ctx: InitContext) -> Result<Vec<PatchResult>> {\n    struct PendingPatch {\n        path: PathBuf,\n        existed: bool,\n        serialized: String,\n    }\n\n    let mut results = Vec::with_capacity(paths.len());\n    let mut pending = Vec::new();\n    let mut applied: Vec<String> = Vec::new();\n\n    // Preflight every target before writing any one of them.\n    for path in paths {\n        let (mut root, existed) = read_trae_hooks_json(path)?;\n        validate_trae_hooks_json(&root)?;\n        let added_version = if root.get(\"version\").is_none() {\n            root.as_object_mut()\n                .expect(\"validated object\")\n                .insert(\"version\".into(), serde_json::json!(1));\n            true\n        } else {\n            false\n        };\n\n        if trae_hook_already_present(&root) && !added_version {\n            results.push(PatchResult::AlreadyPresent);\n            // Already carries the hook, so it counts as updated when a later\n            // target fails -- otherwise a rerun after fixing that failure\n            // reports \"none\" and invites a duplicate hand-edit.\n            applied.push(path.display().to_string());\n            continue;\n        }\n\n        if !trae_hook_already_present(&root) {\n            insert_trae_hook_entry(&mut root)?;\n        }","sourceCodeStart":5116,"sourceCodeEnd":5152,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/hooks/init.rs#L5116-L5152","documentation":"In the Trae hook installer (src/hooks/init.rs), after read_trae_hooks_json and validate_trae_hooks_json succeed, the code calls root.as_object_mut().expect(\"validated object\") to insert a missing \"version\" key. The expect encodes the invariant that validation already proved the root is a JSON object; if validation is correct the unwrap always succeeds. A panic here would indicate validate_trae_hooks_json and the mutation path disagreeing — an internal bug, not user input handling.","triggerScenarios":"insert/patch of Trae hooks.json where root.get(\"version\") is None and the root is mutated; the expect fires only if validate_trae_hooks_json passed a value that is not an object (impossible if validation is intact).","commonSituations":"Only via an rtk regression where validation was weakened/removed or the value was replaced between validation and mutation; users with a valid Trae hooks.json are unaffected.","solutions":["Update rtk and, if reproducible, report the panic with the Trae hooks.json contents","Ensure the Trae hooks.json root is an object containing \"version\": 1 so the insert branch is skipped","Manually add the RTK hook entries to the Trae hooks.json as a workaround"],"exampleFix":"// before\nroot.as_object_mut().expect(\"validated object\").insert(\"version\".into(), serde_json::json!(1));\n// after\nlet obj = root.as_object_mut().ok_or_else(|| anyhow::anyhow!(\"Trae hooks.json root must be an object\"))?;\nobj.insert(\"version\".into(), serde_json::json!(1));","handlingStrategy":"validation","validationCode":"let root: serde_json::Value = serde_json::from_str(&txt)?;\nif !root.is_object() {\n    return Err(anyhow::anyhow!(\"Trae hooks.json root must be an object\"));\n}","typeGuard":"fn is_validated_trae_root(v: &serde_json::Value) -> bool { v.is_object() }","tryCatchPattern":"std::panic::catch_unwind(|| insert_trae_patch(&mut root))\n    .inspect_err(|_| eprintln!(\"'validated object' panic — validation/mutation mismatch, report bug\"));","preventionTips":["Keep Trae hooks.json root as an object with \"version\": 1","Run the validator (or `rtk init`) on a copy first if unsure","Don't strip the validate_trae_hooks_json call when refactoring","Report any occurrence of this expect panicking upstream"],"tags":["rust","serde-json","panic","internal-invariant","hooks","trae"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0924356b4caba4989607227b7c8824d3d8098719","analyzedAt":"2026-09-19T19:25:29.612Z","contentChangedAt":"2026-09-19T19:25:29.612Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}