rtk-ai/rtk · info
just-created json object
Error message
just-created json object
What it means
This .expect() in insert_hook_entry (src/hooks/init.rs) re-borrows root.as_object_mut() immediately after replacing *root with serde_json::json!({}). The fresh value is guaranteed to be an object, so the expect can never fire; it exists to convert Option<&mut Map> into a reference without error plumbing. It is an internal invariant assertion inside rtk's hook installer, hit only if the code's own logic were broken.
Solutions
- Update/reinstall rtk — if you actually see this panic, report it with the settings.json content as a bug
- Inspect the JSON file being patched (settings.json / codex hooks json); a non-object root is replaced automatically, so no user fix is needed
- Work around by ensuring the target hook file's root is a JSON object before running `rtk init`
Example fix
// before
*root = serde_json::json!({});
root.as_object_mut().expect("just-created json object")
// after (panic-free variant)
*root = serde_json::json!({});
root.as_object_mut().ok_or_else(|| anyhow::anyhow!("root is not a JSON object"))? Defensive patterns
Strategy: type-guard
Validate before calling
// Caller-side: ensure the settings root is a JSON object before init patches it
if !value.is_object() {
value = serde_json::json!({});
} Type guard
fn is_json_object(v: &serde_json::Value) -> bool { v.is_object() } Try / catch
// Panics are not catchable in Rust; treat any occurrence as a bug
match std::panic::catch_unwind(|| rtk_init_patch()) {
Ok(_) => {},
Err(_) => eprintln!("rtk init invariant violated — file a bug"),
} Prevention
- Keep settings.json/hook files as JSON objects at the root
- Validate JSON files after manual edits before running `rtk init`
- Report any 'just-created json object' panic upstream with the file content
- Keep rtk updated to pick up invariant fixes
When it happens
Trigger: Calling insert_hook_entry with a non-object root (e.g. null or an array): the function overwrites it with {} and then unwraps — the panic path is unreachable in correct builds but is the designated crash point if the invariant ever breaks.
Common situations: Users do not trigger this directly; it can only surface from a bug in rtk's init code or from fuzzing/dynamic misuse of the internal function via patch_settings_json_command or tests.
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
- validated 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/99bf501a8861555c.
Report an issue: GitHub.
Appendix: source
Thrown at src/hooks/init.rs:1383
let keep = blank_count.min(2);
result.extend(std::iter::repeat_n("", keep));
} else {
result.push(line);
i += 1;
}
}
result.join("\n")
}
/// Deep-merge RTK hook entry into settings.json
/// Creates hooks.PreToolUse structure if missing, preserves existing hooks
fn insert_hook_entry(root: &mut serde_json::Value, hook_command: &str) -> Result<()> {
let root_obj = match root.as_object_mut() {
Some(obj) => obj,
None => {
*root = serde_json::json!({});
root.as_object_mut().expect("just-created json object")
}
};
let hooks = root_obj
.entry("hooks")
.or_insert_with(|| serde_json::json!({}))
.as_object_mut()
.context("hooks value is not an object")?;
let pre_tool_use = hooks
.entry(PRE_TOOL_USE_KEY)
.or_insert_with(|| serde_json::json!([]))
.as_array_mut()
.context("PreToolUse value is not an array")?;
pre_tool_use.push(serde_json::json!({
"matcher": "Bash",
"hooks": [{View on GitHub (pinned to 0924356b4c)