affaan-m/ECC · error

Invalid managed hook handler at

Error message

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

What it means

For hooks of type 'http', the 'url' field is required and must be a non-empty string. validateHookHandler throws this error when an http hook lacks url, has an empty/blank url, or url is some other type (number, object, array).

Solutions

  1. Add a non-empty https/http URL string to the hook, e.g. {type:'http', url:'https://api.example.com/hooks/ecc'}.
  2. Fix misspelled keys (url, not uri/endpoint/target).
  3. Ensure env-based URL templating actually resolves — blank after substitution still fails.
  4. Validate the object before writing settings.

Example fix

// before
{ "type": "http", "endpoint": "https://hooks.example.com/ecc" }
// after
{ "type": "http", "url": "https://hooks.example.com/ecc" }
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

const hasUrl = (h) => h.type !== 'http' || (typeof h.url === 'string' && h.url.trim() !== '');

Try / catch

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

Prevention

When it happens

Trigger: validateManagedHooks encounters {type:'http'} with no url, {type:'http', url:''}, or {type:'http', url:{host:'api.example.com'}}.

Common situations: Hand-written http hook where the url key was omitted or misspelled (endpoint, uri, target); environment-specific URL templating that resolved to an empty string; migrating a webhook entry between config formats.

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

Appendix: source

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

    const validCommand = isNonEmptyString(hook.command)
      || (Array.isArray(hook.command)
        && hook.command.length > 0
        && hook.command.every(isNonEmptyString));
    if (!validCommand) {
      throw new Error(`Invalid managed hook handler at ${label}: invalid command`);
    }
    if (hook.async !== undefined && typeof hook.async !== 'boolean') {
      throw new Error(`Invalid managed hook handler at ${label}: invalid async flag`);
    }
    return;
  }

  if (hook.async !== undefined) {
    throw new Error(`Invalid managed hook handler at ${label}: async requires command type`);
  }
  if (hook.type === 'http') {
    if (!isNonEmptyString(hook.url)) {
      throw new Error(`Invalid managed hook handler at ${label}: invalid url`);
    }
    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)) {

View on GitHub (pinned to 8321021c54)