{"record":{"id":"f057e38fa0ac1b7c","repo":"affaan-m/ECC","slug":"invalid-label-expected-globally-unique-id-entry-id","errorCode":null,"errorMessage":"Invalid ${label}: expected globally unique id \"${entry.id}\"","messagePattern":"Invalid (.+?): expected globally unique id \"(.+?)\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/install/claude-settings.js","lineNumber":160,"sourceCode":"    }\n    if (entries.length === 0) {\n      throw new Error(`Invalid ${label}.${event}: expected at least one hook entry`);\n    }\n\n    entries.forEach((entry, index) => {\n      if (!isJsonObject(entry)) {\n        throw new Error(\n          `Invalid managed hook entry at ${label}.${event}[${index}]: expected a JSON object`\n        );\n      }\n      if (typeof entry.id !== 'string' || entry.id.trim() === '') {\n        throw new Error(\n          `Invalid managed hook entry at ${label}.${event}[${index}]: `\n          + 'expected a non-empty unique id'\n        );\n      }\n      if (seenIds.has(entry.id)) {\n        throw new Error(`Invalid ${label}: expected globally unique id \"${entry.id}\"`);\n      }\n      seenIds.add(entry.id);\n      if (\n        !Object.prototype.hasOwnProperty.call(entry, 'matcher')\n        && !EVENTS_WITHOUT_MATCHER.has(event)\n      ) {\n        throw new Error(\n          `Invalid managed hook entry at ${label}.${event}[${index}]: missing matcher`\n        );\n      }\n      if (\n        Object.prototype.hasOwnProperty.call(entry, 'matcher')\n        && typeof entry.matcher !== 'string'\n        && !isJsonObject(entry.matcher)\n      ) {\n        throw new Error(\n          `Invalid managed hook entry at ${label}.${event}[${index}]: invalid matcher`\n        );","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/install/claude-settings.js#L142-L178","documentation":"Hook entry ids must be globally unique across all events in the managed hooks map, because ids are the lookup key ECC uses to identify its managed hooks in settings.json. validateManagedHooks throws this when a second entry reuses an id already seen earlier in the same map (regardless of event).","triggerScenarios":"Duplicating an entry (copy/paste) with the same id under the same or a different event, e.g. two entries both with id: 'fmt' under PreToolUse and PostToolUse.","commonSituations":"Copy-pasting an entry to add it to another event without renaming the id; generating ids with a function that always returns the same value; merging two hook packs that coincidentally use the same ids.","solutions":["Rename the duplicate entry's id to a new unique value.","Use the quoted id in the message to search the hooks map and locate both occurrences.","If the same hook is genuinely intended on two events, clone it with a distinct id per event (e.g. 'fmt-pre', 'fmt-post').","Generate ids programmatically (event + purpose suffix) to guarantee uniqueness."],"exampleFix":"// before\n{ PreToolUse: [{ id: 'fmt', ... }], PostToolUse: [{ id: 'fmt', ... }] }\n// after\n{ PreToolUse: [{ id: 'fmt-pre', ... }], PostToolUse: [{ id: 'fmt-post', ... }] }","handlingStrategy":"validation","validationCode":"const seen = new Set();\nfor (const entries of Object.values(managedHooks)) {\n  for (const e of entries) {\n    if (seen.has(e.id)) throw new Error(`Duplicate hook id: ${e.id}`);\n    seen.add(e.id);\n  }\n}","typeGuard":"function hasUniqueIds(hooks) {\n  const ids = Object.values(hooks).flat().map(e => e?.id);\n  return ids.length === new Set(ids).size;\n}","tryCatchPattern":"try {\n  expectedHooks(hooks);\n} catch (err) {\n  if (/globally unique id/.test(err.message)) {\n    const dup = err.message.match(/\"([^\"]+)\"/)?.[1];\n    console.error(`Rename one of the entries with id \"${dup}\"`);\n  }\n  throw err;\n}","preventionTips":["Generate ids from event + purpose so duplicates are structurally unlikely","Check uniqueness when merging two hook packs","Never copy-paste an entry across events without renaming its id","Add a duplicate-id unit test for your hook config builder"],"tags":["validation","uniqueness","identifier","hooks"],"backgroundTag":"invalid-identifier","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}