withastro/astro · error · Error

The " " integration is trying to add the " " client…

Error message

The "${integration.name}" integration is trying to add the "${name}" client directive, but it already exists.

What it means

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).

Solutions

  1. Rename the custom directive to something unique, e.g. 'client:hydrate-on-idle' style names or a vendor-prefixed name.
  2. Never attempt to override the built-ins: idle, load, visible, media, only.
  3. If you do not control the integration, disable one of the two colliding integrations or report the conflict to its maintainer.

Example fix

// before - inside an integration
addClientDirective({ name: 'load', entrypoint: 'my-entry' }); // collides with built-in

// after
addClientDirective({ name: 'vendor-load', entrypoint: 'my-entry' }); // use <Comp client:vendor-load ... />
Defensive patterns

Strategy: validation

Validate before calling

// inside an integration, before addClientDirective
const BUILTIN_DIRECTIVES = ['idle', 'load', 'visible', 'media', 'only'];
if (BUILTIN_DIRECTIVES.includes(name)) {
  throw new Error('cannot override built-in client directive: ' + name);
}
addClientDirective({ name, entrypoint });

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/6442d6146da1bf9a. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/integrations/hooks.ts:275

					injectRoute: (injectRoute) => {
						if (injectRoute.entrypoint == null && 'entryPoint' in injectRoute) {
							logger.warn(
								null,
								`The injected route "${injectRoute.pattern}" by ${integration.name} specifies the entry point with the "entryPoint" property. This property is deprecated, please use "entrypoint" instead.`,
							);
							injectRoute.entrypoint = injectRoute.entryPoint as string;
						}
						updatedSettings.injectedRoutes.push({ ...injectRoute, origin: 'external' });
					},
					addWatchFile: (path) => {
						updatedSettings.watchFiles.push(path instanceof URL ? fileURLToPath(path) : path);
					},
					addDevToolbarApp: (entrypoint) => {
						updatedSettings.devToolbarApps.push(entrypoint);
					},
					addClientDirective: ({ name, entrypoint }) => {
						if (updatedSettings.clientDirectives.has(name) || addedClientDirectives.has(name)) {
							throw new Error(
								`The "${integration.name}" integration is trying to add the "${name}" client directive, but it already exists.`,
							);
						}
						// TODO: this should be performed after astro:config:done
						addedClientDirectives.set(
							name,
							buildClientDirectiveEntrypoint(name, entrypoint, settings.config.root),
						);
					},
					addMiddleware: ({ order, entrypoint }) => {
						if (typeof updatedSettings.middlewares[order] === 'undefined') {
							throw new Error(
								`The "${integration.name}" integration is trying to add middleware but did not specify an order.`,
							);
						}
						logger.debug(
							'middleware',
							`The integration ${integration.name} has added middleware that runs ${

View on GitHub (pinned to 52e6c34790)