#12296·oh-my-pi

plugin install appends duplicate dependency key to ~/.omp/plugins/package.json → bun DependencyLoop on next install/upgrade

Author: rastarrCreated Sep 17, 2026Updated Sep 18, 2026

Description

omp install <pkg>@<version> (and omp plugin upgrade) is not idempotent: when the target package's key already exists in ~/.omp/plugins/package.json, the installer appends a duplicate JSON key instead of updating the existing entry in place. JSON allows duplicate keys syntactically, so package.json stays parseable, but the stale first entry survives and bun install (which omp shells out to) then fails with a misleading DependencyLoop error on the next install/upgrade.

This bit me when upgrading a plugin (pi-lens 4.1.6 → 4.2.0): the manifest contained two pi-lens entries — a stale unversioned alias plus the pinned version — and every subsequent omp install npm:[email protected] failed until I hand-deduplicated the file.

I reproduced the append-instead-of-replace behavior deterministically: installing the same version twice in a row re-corrupts the manifest both times, so it is not an artifact of upgrading across versions.

Corrupted manifest (produced by omp itself, ~/.omp/plugins/package.json):

json
{
    "name": "omp-plugins",
    "private": true,
    "dependencies": {
        "pi-lens": "npm:pi-lens",
        "pi-lens": "v4.1.6"
    }
}

After one successful omp install npm:[email protected] against a hand-repaired manifest, a repeat run of the identical command produced:

json
{
    "name": "omp-plugins",
    "private": true,
    "dependencies": {
        "pi-lens": "npm:[email protected]",
        "pi-lens": "npm:[email protected]"
    }
}

Steps to Reproduce

  1. Install any npm plugin: omp install npm:[email protected] → succeeds, manifest gets "pi-lens": "npm:[email protected]".
  2. Run the exact same command again: omp install npm:[email protected] → reports success, but the manifest now contains the "pi-lens" key twice.
  3. Repeat step 2 a few times (or let a stale first entry accumulate from an earlier upgrade). Eventually bun install fails and the CLI surfaces a confusing error.

With a pre-corrupted manifest (duplicate key from a prior upgrade), the failure at step 2 is:

Expected Behavior

  • The installer should replace the existing dependency entry for the same package name rather than appending a second one — installs/upgrades should be idempotent.
  • Ideally omp plugin doctor (or the install path itself) should detect duplicate keys in package.json and offer --fix, since a JSON duplicate is valid syntax but silently breaks the bun resolution.
  • The surfaced error should mention the duplicate-key root cause rather than only bun's downstream DependencyLoop.

Error Output

✘ Failed to install npm:[email protected]: Error: bun install failed: Resolving dependencies
6 |         "pi-lens": "v4.1.6"
    ^
warn: Duplicate key "pi-lens" in object literal
   at /home/martin/.omp/plugins/package.json:6:9
7 |         "pi-lens": "v4.1.6",
    ^
warn: Duplicate key "pi-lens" in object literal
   at bun.lock:9:9
error: Package "[email protected]" has a dependency loop
  Resolution: "[email protected]"
  Dependency: "pi-lens@npm:pi-lens"
error: An internal error occurred (DependencyLoop)

Environment / notes

  • The npm package metadata for the plugin was identical between the failing and working versions (same deps/peerDeps/engines), ruling out the package itself.
  • Installing into a fresh HOME works fine — only manifests with an existing entry trigger the duplicate append.
  • A clean single-key manifest ("pi-lens": "npm:[email protected]") installs and upgrades fine; omp plugin doctor reports all healthy afterwards.

Additional context

Possibly related to #11090 (lock/manifest drift around plugin installs) but that issue describes omp-plugins.lock.json version drift, not duplicate keys in package.json causing DependencyLoop.


Platform: Linux omp version: 18.2.2 Bun version: 1.3.13 Area: Extensions / Plugins Provider: N/A (not provider-specific)