withastro/astro · error · Error

${integration} does not appear to be a valid package name!

Error message

${integration} does not appear to be a valid package name!

What it means

During `astro add`, each requested integration string is parsed by parseIntegrationName (via parseNpmName). If parsing returns null the spec is not a recognizable npm package spec, and `astro add` throws this Error naming the offending input. This runs after assertValidPackageName, so the spec passed the injection guard but still is not a valid npm name.

Source

Thrown at packages/astro/src/cli/add/index.ts:856

async function validateIntegrations(
	integrations: string[],
	flags: yargsParser.Arguments,
	logger: AstroLogger,
): Promise<IntegrationInfo[]> {
	// First, validate all package names to prevent command injection
	for (const integration of integrations) {
		assertValidPackageName(integration);
	}

	const spinner = clack.spinner({ withGuide: false });
	spinner.start('Resolving packages...');
	try {
		const integrationEntries = await Promise.all(
			integrations.map(async (integration): Promise<IntegrationInfo> => {
				const parsed = parseIntegrationName(integration);
				if (!parsed) {
					throw new Error(`${bold(integration)} does not appear to be a valid package name!`);
				}
				let { scope, name, tag } = parsed;
				let pkgJson;
				let pkgType: 'first-party' | 'third-party';

				if (scope && scope !== '@astrojs') {
					pkgType = 'third-party';
				} else {
					const firstPartyPkgCheck = await fetchPackageJson('@astrojs', name, tag);
					if (firstPartyPkgCheck instanceof Error) {
						if (firstPartyPkgCheck.message) {
							spinner.message(yellow(firstPartyPkgCheck.message));
						}
						spinner.message(yellow(`${bold(integration)} is not an official Astro package.`));
						if (!(await askToContinue({ flags, logger }))) {
							throw new Error(
								`No problem! Find our official integrations at ${cyan(
									'https://astro.build/integrations',

View on GitHub (pinned to d081033d5f)

Solutions

  1. Use the npm package name only: `astro add @astrojs/tailwind`, `astro add react`.
  2. For a scoped third-party package, include the full scope: `astro add @myorg/integration`.
  3. Omit registry URLs, versions prefixed wrongly, and file paths.
  4. Re-run with the corrected argument; double-check shell escaping of `@` and `/`.

Example fix

# before
astro add https://registry.npmjs.org/@astrojs/react
astro add @astrojs

# after
astro add @astrojs/react
Defensive patterns

Strategy: validation

Validate before calling

function isValidNpmSpec(spec: string): boolean {
  return /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(?:@[^@]+)?$/.test(spec);
}

Type guard

function isNpmPackageName(v: unknown): v is string {
  return typeof v === 'string' && /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(v);
}

Prevention

When it happens

Trigger: Passing an argument to `astro add` that is not a valid scoped/unscoped npm package spec — e.g. a URL, a path, a name with illegal characters, an empty string, a bare version, or a malformed scoped spec like `@/foo`.

Common situations: Typing `astro add https://example.com/x`; passing `astro add @astrojs`; forgetting the package name within a scope; copy-pasting a registry URL instead of the package name; shell-quoting that drops part of the argument.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/e977e907c34521a8. Report an issue: GitHub.