withastro/astro · error · Error

Invalid package name "${packageName}". Package names must fo

Error message

Invalid package name "${packageName}". Package names must follow npm naming rules: lowercase letters, numbers, hyphens, underscores, and dots. Scoped packages like @org/package are also supported.

What it means

Thrown by `assertValidPackageName()` in @astrojs/internal-helpers when a string fails the npm naming regex `/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/`. The helper guards CLI commands against shell-metacharacter injection and malformed package references.

Source

Thrown at packages/internal-helpers/src/cli.ts:43

export function validatePackageName(packageName: string): boolean {
	return NPM_PACKAGE_NAME_REGEX.test(packageName);
}

/**
 * Validates a package name and throws an error if invalid.
 *
 * @param packageName - The package name to validate
 * @throws {Error} If the package name is invalid
 *
 * @example
 * ```ts
 * assertValidPackageName('react'); // OK
 * assertValidPackageName('react; whoami'); // throws Error
 * ```
 */
export function assertValidPackageName(packageName: string): asserts packageName is string {
	if (!validatePackageName(packageName)) {
		throw new Error(
			`Invalid package name "${packageName}". Package names must follow npm naming rules: ` +
				`lowercase letters, numbers, hyphens, underscores, and dots. ` +
				`Scoped packages like @org/package are also supported.`,
		);
	}
}

View on GitHub (pinned to d081033d5f)

Solutions

  1. Sanitize/normalize the name to lowercase before passing it in.
  2. Validate with `validatePackageName(name)` first and surface a friendly error to end users.
  3. Reject names with shell metacharacters at the input boundary; never interpolate raw CLI args into package names.

Example fix

// before
assertValidPackageName(inputFromUser); // throws on 'react; whoami'
// after
if (!validatePackageName(inputFromUser)) {
  throw new Error('Please enter a valid npm package name.');
}
assertValidPackageName(inputFromUser.toLowerCase());
Defensive patterns

Strategy: type-guard

Validate before calling

import { validatePackageName } from '@astrojs/internal-helpers';
if (!validatePackageName(input)) {
  throw new Error(`'${input}' is not a valid npm package name.`);
}
assertValidPackageName(input.toLowerCase());

Type guard

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

Try / catch

try { assertValidPackageName(name); } catch (e) { if (/Invalid package name/) { /* prompt user again */ } else throw e; }

Prevention

When it happens

Trigger: Passing user/CLI input containing `;`, `&`, `$`, spaces, uppercase, or other disallowed chars to a command that builds package names (e.g. an `astro add`/create flow). A scoped package with uppercase scope. A name starting with `.` or `_`.

Common situations: Accepting a package name from a prompt or env var without sanitizing. A typo like `@Org/Package` (uppercase) or `react; rm -rf /`. Nested scopes (`@a/b/c`) which the regex forbids.

Related errors


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