{"record":{"id":"6442d6146da1bf9a","repo":"withastro/astro","slug":"the-integration-name-integration-is-trying-to","errorCode":null,"errorMessage":"The \"${integration.name}\" integration is trying to add the \"${name}\" client directive, but it already exists.","messagePattern":"The \"(.+?)\" integration is trying to add the \"(.+?)\" client directive, but it already exists\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/integrations/hooks.ts","lineNumber":275,"sourceCode":"\t\t\t\t\tinjectRoute: (injectRoute) => {\n\t\t\t\t\t\tif (injectRoute.entrypoint == null && 'entryPoint' in injectRoute) {\n\t\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t`The injected route \"${injectRoute.pattern}\" by ${integration.name} specifies the entry point with the \"entryPoint\" property. This property is deprecated, please use \"entrypoint\" instead.`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tinjectRoute.entrypoint = injectRoute.entryPoint as string;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdatedSettings.injectedRoutes.push({ ...injectRoute, origin: 'external' });\n\t\t\t\t\t},\n\t\t\t\t\taddWatchFile: (path) => {\n\t\t\t\t\t\tupdatedSettings.watchFiles.push(path instanceof URL ? fileURLToPath(path) : path);\n\t\t\t\t\t},\n\t\t\t\t\taddDevToolbarApp: (entrypoint) => {\n\t\t\t\t\t\tupdatedSettings.devToolbarApps.push(entrypoint);\n\t\t\t\t\t},\n\t\t\t\t\taddClientDirective: ({ name, entrypoint }) => {\n\t\t\t\t\t\tif (updatedSettings.clientDirectives.has(name) || addedClientDirectives.has(name)) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`The \"${integration.name}\" integration is trying to add the \"${name}\" client directive, but it already exists.`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// TODO: this should be performed after astro:config:done\n\t\t\t\t\t\taddedClientDirectives.set(\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tbuildClientDirectiveEntrypoint(name, entrypoint, settings.config.root),\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\taddMiddleware: ({ order, entrypoint }) => {\n\t\t\t\t\t\tif (typeof updatedSettings.middlewares[order] === 'undefined') {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`The \"${integration.name}\" integration is trying to add middleware but did not specify an order.`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t\t'middleware',\n\t\t\t\t\t\t\t`The integration ${integration.name} has added middleware that runs ${","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/integrations/hooks.ts#L257-L293","documentation":"Client directives (the `client:*` part of a component tag) are registered by name. During `astro:config:setup`, addClientDirective() throws this plain Error when the directive name being added is already registered - either in `settings.clientDirectives` (built-ins like idle, load, visible, media, only) or among directives added earlier in the same setup run (addedClientDirectives).","triggerScenarios":"An integration calling addClientDirective({ name: 'load', entrypoint }) - 'load' is built in; two integrations registering the same custom name; an integration re-registering on config restarts without guarding (the in-run set plus settings both count).","commonSituations":"Authoring an integration that adds a custom client directive whose name collides with a built-in; using multiple integrations that both add a similarly named directive; picking a generic name like 'visible' or 'idle' for a custom directive.","solutions":["Rename the custom directive to something unique, e.g. 'client:hydrate-on-idle' style names or a vendor-prefixed name.","Never attempt to override the built-ins: idle, load, visible, media, only.","If you do not control the integration, disable one of the two colliding integrations or report the conflict to its maintainer."],"exampleFix":"// before - inside an integration\naddClientDirective({ name: 'load', entrypoint: 'my-entry' }); // collides with built-in\n\n// after\naddClientDirective({ name: 'vendor-load', entrypoint: 'my-entry' }); // use <Comp client:vendor-load ... />","handlingStrategy":"validation","validationCode":"// inside an integration, before addClientDirective\nconst BUILTIN_DIRECTIVES = ['idle', 'load', 'visible', 'media', 'only'];\nif (BUILTIN_DIRECTIVES.includes(name)) {\n  throw new Error('cannot override built-in client directive: ' + name);\n}\naddClientDirective({ name, entrypoint });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Vendor-prefix custom directive names (client:vendor-load) to avoid collisions.","Never attempt to re-register the built-ins idle, load, visible, media, only.","When composing multiple integrations that add directives, document the registered names."],"tags":["integrations","client-directives","plugin-api"],"backgroundTag":"duplicate-name-registration","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}