rtk-ai/rtk · error

Trae PreToolUse value is not an array

Error message

Trae PreToolUse value is not an array

What it means

Trae hooks.json validation step three: if the `hooks` object contains a PreToolUse entry (`PRE_TOOL_USE_KEY`), its value must be a JSON array of hook commands. If it exists with another type (object, string, number), rtk bails because it appends its hook to that array and cannot merge into any other shape.

Solutions

  1. Wrap the PreToolUse value in an array: `"PreToolUse": [<existing-hook>]`.
  2. If unsure, back up the file, remove the PreToolUse key, and rerun `rtk init` so rtk writes a correct array entry.
  3. Validate the JSON structure against a known-good Trae hooks.json before rerunning.

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

const preToolUseOk = (j) => j?.hooks?.PreToolUse === undefined || Array.isArray(j.hooks.PreToolUse);

Try / catch

match rtk init result { Err if msg contains 'PreToolUse value is not an array' => wrap the value in an array and retry }

Prevention

When it happens

Trigger: Running `rtk init` for Trae where existing `.trae/hooks.json` has `hooks.PreToolUse` present but not an array (e.g. a single object instead of an array of hook entries).

Common situations: User or another tool wrote PreToolUse as a single hook object instead of an array; hand-edit flattened the list; template copied from a tool with a different hooks schema.

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/e5eccf6151a5d515. Report an issue: GitHub.

Appendix: source

Thrown at src/hooks/init.rs:5109

        .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,
        serialized: String,
    }

    let mut results = Vec::with_capacity(paths.len());
    let mut pending = Vec::new();
    let mut applied: Vec<String> = Vec::new();

View on GitHub (pinned to 0924356b4c)