{"record":{"id":"c7a0ca17162fc01a","repo":"shadcn-ui/ui","slug":"invalid-dependency-dep-dependency-names-cann","errorCode":null,"errorMessage":"Invalid dependency \"${dep}\": dependency names cannot start with \"-\".","messagePattern":"Invalid dependency \"(.+?)\": dependency names cannot start with \"-\"\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/shadcn/src/utils/updaters/update-dependencies.ts","lineNumber":211,"sourceCode":"    // https://docs.expo.dev/more/expo-cli/#install\n    return \"expo\"\n  }\n\n  return getPackageManager(config.resolvedPaths.cwd)\n}\n\n/**\n * Registry-supplied dependency strings are forwarded directly into the package\n * manager's argument list. A specifier beginning with \"-\" would be interpreted\n * as a flag rather than a package name, letting a malicious registry alter the\n * install source/behavior (argument injection). Reject those before they reach\n * `execa`; the `--` end-of-options separator added at each call site is the\n * second layer of defense.\n */\nexport function assertSafeDependencies(deps: string[]) {\n  for (const dep of deps) {\n    if (dep.trim().startsWith(\"-\")) {\n      throw new Error(\n        `Invalid dependency \"${dep}\": dependency names cannot start with \"-\".`\n      )\n    }\n  }\n}\n\nasync function installWithPackageManager(\n  packageManager: Awaited<\n    ReturnType<typeof getUpdateDependenciesPackageManager>\n  >,\n  dependencies: string[],\n  devDependencies: string[],\n  cwd: string,\n  flag?: string\n) {\n  if (packageManager === \"npm\") {\n    return installWithNpm(dependencies, devDependencies, cwd, flag)\n  }","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/utils/updaters/update-dependencies.ts#L193-L229","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// registry item (before)\n{ \"dependencies\": [\"--registry=https://evil.example.com\"] }\n// after\n{ \"dependencies\": [\"clsx\", \"tailwind-merge\"] }","handlingStrategy":"validation","validationCode":"function assertSafeDependencies(deps: string[]) {\n  for (const dep of deps) {\n    if (dep.trim().startsWith(\"-\")) {\n      throw new Error(`unsafe dependency: ${dep}`)\n    }\n  }\n}\nassertSafeDependencies(item.dependencies ?? [])\nassertSafeDependencies(item.devDependencies ?? [])","typeGuard":"const areSafeDependencies = (deps: string[]) =>\n  deps.every((d) => !d.trim().startsWith(\"-\"))","tryCatchPattern":"try {\n  await updateDependencies(tree, config)\n} catch (e) {\n  if (e instanceof Error && /dependency names cannot start/.test(e.message)) {\n    // strip the offending dep and report the registry as untrusted\n  }\n  throw e\n}","preventionTips":["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."],"tags":["security","dependencies","argument-injection","registry"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}