{"record":{"id":"a88c16cd6cd60026","repo":"rtk-ai/rtk","slug":"trae-hooks-json-version-must-be-1","errorCode":null,"errorMessage":"Trae hooks.json version must be 1","messagePattern":"Trae hooks\\.json version must be 1","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/hooks/init.rs","lineNumber":5096,"sourceCode":"    }\n}\n\nfn read_trae_hooks_json(path: &Path) -> Result<(serde_json::Value, bool)> {\n    match read_json_file(path)? {\n        Some(root) => Ok((root, true)),\n        None => Ok((serde_json::json!({ \"version\": 1 }), false)),\n    }\n}\n\nfn validate_trae_hooks_json(root: &serde_json::Value) -> Result<()> {\n    let root_object = root\n        .as_object()\n        .context(\"Trae hooks.json root must be an object\")?;\n    if root_object\n        .get(\"version\")\n        .is_some_and(|version| version != &serde_json::json!(1))\n    {\n        anyhow::bail!(\"Trae hooks.json version must be 1\");\n    }\n    if root_object\n        .get(\"hooks\")\n        .is_some_and(|hooks| !hooks.is_object())\n    {\n        anyhow::bail!(\"Trae hooks value is not an object\");\n    }\n    if root_object\n        .get(\"hooks\")\n        .and_then(|hooks| hooks.get(PRE_TOOL_USE_KEY))\n        .is_some_and(|pre_tool_use| !pre_tool_use.is_array())\n    {\n        anyhow::bail!(\"Trae PreToolUse value is not an array\");\n    }\n    Ok(())\n}\n\n/// Install RTK's Trae hook in every supplied target. All targets are read and","sourceCodeStart":5078,"sourceCodeEnd":5114,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/hooks/init.rs#L5078-L5114","documentation":"rtk validates an existing Trae `hooks.json` before merging its hook entries. The schema requires the top-level `version` field to be exactly the JSON number 1. If `version` is present with any other value (or type), rtk bails because it only knows how to safely merge into version-1 Trae hook configs.","triggerScenarios":"Running `rtk init` for Trae where `.trae/hooks.json` (or `.trae-cn/hooks.json`) exists and its parsed JSON root has a `version` field not equal to `serde_json::json!(1)` — e.g. 2, \"1\" as a string, or null.","commonSituations":"Hand-edited hooks.json with a bumped version; a different tool wrote a newer schema version; version stored as a string instead of a number.","solutions":["Edit hooks.json and set `\"version\": 1` (number, not string).","If the file was written by a newer Trae version, update rtk or migrate the hooks manually into a version-1 file.","Back up and reset hooks.json to a minimal `{\"version\":1,\"hooks\":{}}` and rerun `rtk init`."],"exampleFix":"// before (.trae/hooks.json)\n{ \"version\": 2, \"hooks\": {} }\n// after\n{ \"version\": 1, \"hooks\": {} }","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nfunction traeready(p = '.trae/hooks.json') {\n  if (!fs.existsSync(p)) return true;\n  const j = JSON.parse(fs.readFileSync(p, 'utf8'));\n  return j.version === undefined || j.version === 1; // must be number 1\n}","typeGuard":"const isV1 = (j) => typeof j === 'object' && j !== null && (j.version === undefined || j.version === 1);","tryCatchPattern":"match rtk init result { Err if msg contains 'version must be 1' => fix version field and retry }","preventionTips":["Never change `version` in .trae/hooks.json by hand.","Store version as a JSON number, never a string.","Pin the Trae schema version expected by your rtk version."],"tags":["json","schema-validation","trae","hooks"],"backgroundTag":"schema-validation-failed","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"}