{"record":{"id":"bd7472562272a500","repo":"withastro/astro","slug":"invalid-package-name-packagename-package-nam","errorCode":null,"errorMessage":"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.","messagePattern":"Invalid package name \"(.+?)\"\\. Package names must follow npm naming rules: lowercase letters, numbers, hyphens, underscores, and dots\\. Scoped packages like @org/package are also supported\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/internal-helpers/src/cli.ts","lineNumber":43,"sourceCode":"export function validatePackageName(packageName: string): boolean {\n\treturn NPM_PACKAGE_NAME_REGEX.test(packageName);\n}\n\n/**\n * Validates a package name and throws an error if invalid.\n *\n * @param packageName - The package name to validate\n * @throws {Error} If the package name is invalid\n *\n * @example\n * ```ts\n * assertValidPackageName('react'); // OK\n * assertValidPackageName('react; whoami'); // throws Error\n * ```\n */\nexport function assertValidPackageName(packageName: string): asserts packageName is string {\n\tif (!validatePackageName(packageName)) {\n\t\tthrow new Error(\n\t\t\t`Invalid package name \"${packageName}\". Package names must follow npm naming rules: ` +\n\t\t\t\t`lowercase letters, numbers, hyphens, underscores, and dots. ` +\n\t\t\t\t`Scoped packages like @org/package are also supported.`,\n\t\t);\n\t}\n}\n","sourceCodeStart":25,"sourceCodeEnd":50,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/internal-helpers/src/cli.ts#L25-L50","documentation":"`assertValidPackageName` in @astrojs/internal-helpers validates that a string is a legal npm package name before it is passed to package-manager commands. It is a command-injection and typo guard: names like `react; whoami` would otherwise be forwarded to spawned npm/pnpm/bun commands. The message enumerates the accepted shape (lowercase letters, numbers, hyphens, underscores, dots, and @scope/name).","triggerScenarios":"Running `astro add \"react; rm -rf ~\"` or any argument with spaces/semicolons; passing an uppercase name (`astro add React`); appending a version (`astro add react@19`) if the validator rejects the `@version` suffix; passing an empty or malformed scoped name like `@/pkg`.","commonSituations":"Shell scripts or CI pipelines interpolating untrusted strings into `astro add`; users assuming `astro add` accepts version specifiers like `npm install` does; copy-pasting package names with stray whitespace or quotes.","solutions":["Pass a plain, lowercase npm package name: `astro add react`","For scoped integrations use `astro add @astrojs/sitemap`","If you need a specific version, add it afterwards with your package manager (`npm i astro@5.0.0`), not via `astro add`","If the name comes from user input in a script, validate it first with the same npm naming rules"],"exampleFix":"# before\nastro add \"tailwind@4\"\n\n# after\nastro add tailwind\nnpx astro tailwind add  # then manage versions via the package manager","handlingStrategy":"validation","validationCode":"import validatePackageName from 'validate-npm-package-name';\nfunction safePkgName(input: string): string | null {\n  return validatePackageName(input).validForNewPackages ? input : null;\n}","typeGuard":"function isValidNpmName(name: string): boolean {\n  return /^(?:@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(name);\n}","tryCatchPattern":null,"preventionTips":["Never interpolate untrusted shell input into `astro add`","Pass plain lowercase npm names; handle versions with the package manager itself","In scripts wrapping astro add, validate names first with validate-npm-package-name"],"tags":["cli","astro-add","package-name","validation","security"],"backgroundTag":"invalid-package-name","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"}