affaan-m/ECC · error

Invalid managed hook handler at

Error message

Invalid managed hook handler at ${label}: invalid prompt

What it means

Hooks that are not of type 'command' or 'http' (i.e. prompt/agent hooks) must have a 'prompt' field that is a non-empty string. validateHookHandler throws this error when such a hook lacks prompt, has a blank prompt, or prompt is a non-string value.

Solutions

  1. Add a non-empty prompt string: {type:'prompt', prompt:'Review the staged diff for security issues'}.
  2. Rename instruction/message/text keys to prompt.
  3. Join any array-of-lines into a single string (e.g. lines.join('\n')).
  4. Check that template interpolation did not produce an empty string.

Example fix

// before
{ "type": "prompt", "instruction": "Summarize the changes" }
// after
{ "type": "prompt", "prompt": "Summarize the changes" }
Defensive patterns

Strategy: validation

Validate before calling

const bad = hooks.filter(h=>h.type!=='command'&&h.type!=='http'&&!(typeof h.prompt==='string'&&h.prompt.trim()!=='')); if (bad.length) throw new Error('prompt hooks need non-empty prompt');

Type guard

const hasPrompt = (h) => ['command','http'].includes(h.type) || (typeof h.prompt === 'string' && h.prompt.trim() !== '');

Try / catch

try { installHooks(cfg); } catch (e) { if (e.message.includes('invalid prompt')) { console.error('Prompt/agent hook missing prompt text:', e.message); process.exitCode = 1; } else throw e; }

Prevention

When it happens

Trigger: validateManagedHooks encounters {type:'prompt'} with no prompt, {type:'prompt', prompt:''}, {type:'prompt', prompt:["step1","step2"]}, or {type:'agent', agent:'reviewer'} missing prompt.

Common situations: Prompt hooks authored with the instruction text under another key (instruction, message, text); multi-line prompts stored as arrays; copying a command hook and forgetting to add prompt; empty prompt after template variable substitution.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/198282ecbaeca829. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/install/claude-settings.js:120

    }
    if (
      hook.headers !== undefined
      && (!isJsonObject(hook.headers)
        || !Object.values(hook.headers).every(value => typeof value === 'string'))
    ) {
      throw new Error(`Invalid managed hook handler at ${label}: invalid headers`);
    }
    if (
      hook.allowedEnvVars !== undefined
      && (!Array.isArray(hook.allowedEnvVars)
        || !hook.allowedEnvVars.every(isNonEmptyString))
    ) {
      throw new Error(`Invalid managed hook handler at ${label}: invalid allowedEnvVars`);
    }
    return;
  }
  if (!isNonEmptyString(hook.prompt)) {
    throw new Error(`Invalid managed hook handler at ${label}: invalid prompt`);
  }
  if (hook.model !== undefined && !isNonEmptyString(hook.model)) {
    throw new Error(`Invalid managed hook handler at ${label}: invalid model`);
  }
}

function validateManagedHooks(managedHooks, label = 'managed hooks') {
  if (!isJsonObject(managedHooks)) {
    throw new Error(`Invalid ${label}: expected a JSON object`);
  }
  if (Object.keys(managedHooks).length === 0) {
    throw new Error(`Invalid ${label}: expected at least one hook event`);
  }

  const seenIds = new Set();
  for (const [event, entries] of Object.entries(managedHooks)) {
    if (!VALID_EVENTS.has(event)) {
      throw new Error(`Invalid ${label}: unsupported hook event "${event}"`);

View on GitHub (pinned to 8321021c54)