rtk-ai/rtk · info
validated object
Error message
validated object
What it means
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.
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
Example fix
// before
root.as_object_mut().expect("validated object").insert("version".into(), serde_json::json!(1));
// after
let obj = root.as_object_mut().ok_or_else(|| anyhow::anyhow!("Trae hooks.json root must be an object"))?;
obj.insert("version".into(), serde_json::json!(1)); Defensive patterns
Strategy: validation
Validate before calling
let root: serde_json::Value = serde_json::from_str(&txt)?;
if !root.is_object() {
return Err(anyhow::anyhow!("Trae hooks.json root must be an object"));
} Type guard
fn is_validated_trae_root(v: &serde_json::Value) -> bool { v.is_object() } Try / catch
std::panic::catch_unwind(|| insert_trae_patch(&mut root))
.inspect_err(|_| eprintln!("'validated object' panic — validation/mutation mismatch, report bug")); Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- just-created json object
- hg diff must parse
- hg log -p must parse
- invalid ctest result prefix regex
- invalid ctest result terminator regex
AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19).
Data as JSON: /api/errors/924718e46f64238c.
Report an issue: GitHub.
Appendix: source
Thrown at src/hooks/init.rs:5134
/// cannot cause a partially-applied update.
fn patch_trae_hooks_json_paths(paths: &[PathBuf], ctx: InitContext) -> Result<Vec<PatchResult>> {
struct PendingPatch {
path: PathBuf,
existed: bool,
serialized: String,
}
let mut results = Vec::with_capacity(paths.len());
let mut pending = Vec::new();
let mut applied: Vec<String> = Vec::new();
// Preflight every target before writing any one of them.
for path in paths {
let (mut root, existed) = read_trae_hooks_json(path)?;
validate_trae_hooks_json(&root)?;
let added_version = if root.get("version").is_none() {
root.as_object_mut()
.expect("validated object")
.insert("version".into(), serde_json::json!(1));
true
} else {
false
};
if trae_hook_already_present(&root) && !added_version {
results.push(PatchResult::AlreadyPresent);
// Already carries the hook, so it counts as updated when a later
// target fails -- otherwise a rerun after fixing that failure
// reports "none" and invites a duplicate hand-edit.
applied.push(path.display().to_string());
continue;
}
if !trae_hook_already_present(&root) {
insert_trae_hook_entry(&mut root)?;
}View on GitHub (pinned to 0924356b4c)