rtk-ai/rtk · error

Trae hooks value is not an object

Error message

Trae hooks value is not an object

What it means

During Trae hooks.json validation, if a `hooks` key is present it must be a JSON object mapping hook events to their entries. If `hooks` exists but is an array, string, number, etc., rtk bails because it cannot merge RTK's PreToolUse hook into a malformed structure.

Solutions

  1. Edit hooks.json so `hooks` is an object, e.g. `{"version":1,"hooks":{}}`.
  2. Compare against a working Trae hooks.json from another project and fix the structure.
  3. Back up and reset the file to the minimal valid skeleton, then rerun `rtk init` to let rtk write the hook.

Example fix

// before (.trae/hooks.json)
{ "version": 1, "hooks": [] }
// after
{ "version": 1, "hooks": {} }
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
function hooksIsObject(p = '.trae/hooks.json') {
  if (!fs.existsSync(p)) return true;
  const j = JSON.parse(fs.readFileSync(p, 'utf8'));
  return j.hooks === undefined || (typeof j.hooks === 'object' && !Array.isArray(j.hooks));
}

Type guard

const hooksOk = (j) => j.hooks === undefined || (typeof j.hooks === 'object' && j.hooks !== null && !Array.isArray(j.hooks));

Try / catch

match rtk init result { Err if msg contains 'hooks value is not an object' => restructure hooks as an object and retry }

Prevention

When it happens

Trigger: Running `rtk init` for Trae where the existing `.trae/hooks.json` (or `.trae-cn`) parses as JSON and has a `hooks` field whose value is not an object (e.g. an array or string).

Common situations: Manual editing mistakes (bracket slipped, `hooks` written as a list); another tool generated an incompatible layout; copy-paste corruption of the config.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19). Data as JSON: /api/errors/2c72f2a0d79a022c. Report an issue: GitHub.

Appendix: source

Thrown at src/hooks/init.rs:5102

        None => Ok((serde_json::json!({ "version": 1 }), false)),
    }
}

fn validate_trae_hooks_json(root: &serde_json::Value) -> Result<()> {
    let root_object = root
        .as_object()
        .context("Trae hooks.json root must be an object")?;
    if root_object
        .get("version")
        .is_some_and(|version| version != &serde_json::json!(1))
    {
        anyhow::bail!("Trae hooks.json version must be 1");
    }
    if root_object
        .get("hooks")
        .is_some_and(|hooks| !hooks.is_object())
    {
        anyhow::bail!("Trae hooks value is not an object");
    }
    if root_object
        .get("hooks")
        .and_then(|hooks| hooks.get(PRE_TOOL_USE_KEY))
        .is_some_and(|pre_tool_use| !pre_tool_use.is_array())
    {
        anyhow::bail!("Trae PreToolUse value is not an array");
    }
    Ok(())
}

/// Install RTK's Trae hook in every supplied target. All targets are read and
/// parsed before any write, so malformed `.trae` or `.trae-cn` configuration
/// 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,

View on GitHub (pinned to 0924356b4c)