affaan-m/ECC · error

Invalid managed hook handler at

Error message

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

What it means

For http hooks, the optional 'allowedEnvVars' field must be an array of non-empty strings naming environment variables the hook may read. validateHookHandler throws this error when it is not an array or contains blank/non-string entries.

Solutions

  1. Wrap the value in an array: allowedEnvVars:["MY_API_TOKEN"].
  2. Remove empty or whitespace-only entries from the array.
  3. Ensure every entry is a string env var name, not a value or number.
  4. Validate with Array.isArray and every(isNonEmptyString) before calling the API.

Example fix

// before
{ "type": "http", "url": "https://api.example.com", "allowedEnvVars": "GITHUB_TOKEN" }
// after
{ "type": "http", "url": "https://api.example.com", "allowedEnvVars": ["GITHUB_TOKEN"] }
Defensive patterns

Strategy: validation

Validate before calling

const bad = hooks.filter(h=>h.type==='http'&&h.allowedEnvVars!==undefined&&(!Array.isArray(h.allowedEnvVars)||!h.allowedEnvVars.every(v=>typeof v==='string'&&v.trim()!==''))); if (bad.length) throw new Error('allowedEnvVars must be string[]');

Type guard

const hasValidEnvVars = (h) => h.allowedEnvVars === undefined || (Array.isArray(h.allowedEnvVars) && h.allowedEnvVars.every(v => typeof v === 'string' && v.trim() !== ''));

Try / catch

try { installHooks(cfg); } catch (e) { if (e.message.includes('invalid allowedEnvVars')) { console.error('allowedEnvVars must be an array of non-empty strings:', e.message); process.exitCode = 1; } else throw e; }

Prevention

When it happens

Trigger: validateManagedHooks encounters {type:'http', url:'x', allowedEnvVars:'ENV_VAR'} (string not array), allowedEnvVars:[''], allowedEnvVars:[42], or allowedEnvVars:{} .

Common situations: Specifying a single env var as a bare string instead of a one-element array; env var names with trailing whitespace; a config generator that emits null entries; misunderstanding that the field is a list, not a map.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

    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)) {
    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`);
  }

View on GitHub (pinned to 8321021c54)