Skip to content

[BUG] Adding entry to vlt.json catalog + switching workspace package.json to catalog: does not update lockfile workspace edges #1610

@lukekarrys

Description

@lukekarrys

✅ Expected Behavior

When I:

  1. Add a new entry to the catalog in vlt.json, and
  2. Edit a workspace package.json to switch a dep from a literal range (e.g. "^5.9.3") to "catalog:",

…running vlt install should rewrite the workspace dep edge in vlt-lock.json from dev ^5.9.3 ~npm~<pkg>@5.9.3 to dev catalog: ~npm~<pkg>@5.9.3, so future bumps to the catalog entry actually flow through to the workspace.

❌ Actual Behavior

vlt install reports added: 0, changed: 0, removed: 0 and:

  • ✅ The lockfile's top-level options.catalog snapshot does get updated to include the new entry.
  • ❌ The workspace dep edge in vlt-lock.json does not get rewritten. It still records the literal version (dev ^5.9.3 ~npm~typescript@5.9.3) instead of dev catalog: ~npm~typescript@5.9.3.

The two halves of the lockfile are now inconsistent: options.catalog lists typescript, but no workspace edge actually references the catalog. As a result, future edits to the catalog entry won't trigger any reinstall, defeating the whole point of cataloging the dep.

The only way I found to get the lockfile back into a consistent state was a full clean: rm vlt-lock.json && vlr wipe && vlt install.

🔄 Steps to Reproduce

mkdir vlt-catalog-bug && cd vlt-catalog-bug

cat > vlt.json <<'JSON'
{
  "workspaces": ["packages/*"],
  "catalog": {
    "vitest": "^4.1.4"
  }
}
JSON

cat > package.json <<'JSON'
{ "name": "vlt-catalog-bug", "private": true }
JSON

mkdir -p packages/a
cat > packages/a/package.json <<'JSON'
{
  "name": "a",
  "version": "0.0.0",
  "devDependencies": {
    "typescript": "^5.9.3",
    "vitest": "catalog:"
  }
}
JSON

vlt install
grep '"workspace.*typescript"' vlt-lock.json
# => "workspace~packages+a typescript": "dev ^5.9.3 ~npm~typescript@5.9.3"

# Now: add typescript to the catalog and switch the workspace dep to catalog:
cat > vlt.json <<'JSON'
{
  "workspaces": ["packages/*"],
  "catalog": {
    "typescript": "^5.9.3",
    "vitest": "^4.1.4"
  }
}
JSON

cat > packages/a/package.json <<'JSON'
{
  "name": "a",
  "version": "0.0.0",
  "devDependencies": {
    "typescript": "catalog:",
    "vitest": "catalog:"
  }
}
JSON

vlt install
# {
#   "add": [], "added": 0,
#   "change": [], "changed": 0,
#   "remove": [], "removed": 0
# }

grep -A 5 '"options"' vlt-lock.json
#   "options": {
#     "catalog": {
#       "typescript": "^5.9.3",   <-- snapshot WAS updated
#       "vitest": "^4.1.4"
#     }
#   },

grep '"workspace.*typescript"' vlt-lock.json
# "workspace~packages+a typescript": "dev ^5.9.3 ~npm~typescript@5.9.3"
#                                          ^^^^^^^ should be `catalog:`

🌍 Environment

  • OS: darwin v24.15.0
  • Node: v24.15.0
  • vlt: 1.0.0-rc.27

🔄 Frequency

Always - Happens every time

📈 Regression Check

Looks like a regression / incomplete fix of:

Both were closed as completed but this exact scenario (catalog added in vlt.json + workspace package.json switched to catalog:) still requires a full clean to take effect.

🛠️ Workaround

rm vlt-lock.json && vlr wipe && vlt install

After this, the workspace edge correctly shows dev catalog: ~npm~typescript@5.9.3 and options.catalog matches.

📎 Additional Context

Hit while migrating typescript to a catalog entry in a real monorepo (vltpkg/vlt.io-2) — every workspace already resolved to the same typescript@5.9.3, so the goal was to centralize the spec without changing resolved versions. The package.json edits were correct and vlt install exited cleanly, but the lockfile still recorded the old literal specs on every workspace edge. Took a wipe to notice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions