# No conflicting duplicate package versions

- **Pattern:** `ab-000678` (`code-maintainability.dependency-management.no-duplicate-deps`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000678
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000678)

## Why it matters

Duplicate versions of shared packages in the lock file trigger the infamous "Invalid hook call" error for React and produce silent type mismatches, doubled bundle size, and non-deterministic runtime behavior when two copies of the same module hold separate module-level state. When `react`, `react-dom`, `graphql`, or `@types/*` resolve to multiple versions, instanceof checks fail across module boundaries, context providers stop propagating to consumers imported from the other copy, and production bugs surface only on specific code paths. This directly undermines dependency-coherence hygiene and turns routine upgrades into days-long debugging sessions.

## Severity rationale

Low because most duplicate sub-dependencies are harmless, but conflicts on framework packages like React escalate quickly to production breakage.

## Remediation

Run `npm ls <package>` (or `pnpm why <package>` / `yarn why <package>`) to locate the offending duplicate, then `npm dedupe` to collapse compatible ranges. When an upstream dependency pins an older version, force a single resolution via the `overrides` field in `package.json` and verify the dependent package still works:

```json
{
  "overrides": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
```

Also remove any package listed in both `dependencies` and `devDependencies`.

## Detection

- **ID:** `no-duplicate-deps`
- **Severity:** `low`
- **What to look for:** Examine the lock file (`package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`) for instances where the same package appears at multiple versions. This happens when two dependencies require incompatible versions of a shared sub-dependency. Common culprits: `react` (multiple versions cause runtime crashes), `graphql`, `@types/*` packages. Also check `package.json` directly for packages listed in both `dependencies` and `devDependencies`.
- **Pass criteria:** Count all packages that appear at multiple versions in the lock file. No critical shared packages (especially `react`, `react-dom`, framework packages) appear at multiple versions. No more than 3 total duplicate packages across the lock file. Report the count: "Found X packages at multiple versions in lock file."
- **Fail criteria:** `react` or `react-dom` appears at multiple versions in the lock file, OR a package appears in both `dependencies` and `devDependencies` in `package.json`.
- **Skip (N/A) when:** No lock file present (this is caught by the `lockfile-present` check in Code Hygiene). Signal: no lock file detected.
- **Detail on fail:** `"react appears at two versions in package-lock.json: 18.3.1 (direct) and 17.0.2 (via a dependency). This can cause runtime 'multiple React instances' errors."` or `"@types/node listed in both dependencies and devDependencies with conflicting versions."`
- **Remediation:** Duplicate React versions in particular cause the "Invalid hook call" error and similar mysterious runtime failures. To identify and resolve:

  ```bash
  # For npm — check for duplicate packages
  npm ls react
  # Look for entries with deduped or multiple versions listed

  # Force deduplication
  npm dedupe
  ```

  If the duplicate is caused by an upstream package requiring an old version, you can override it in `package.json`:
  ```json
  "overrides": {
    "react": "^18.0.0"
  }
  ```

  Use overrides carefully — verify the dependent package actually works with the forced version.

Taxons: dependency-coherence

HTML version: https://auditbuffet.com/patterns/ab-000678
