Skip to content

bun: support bun.lock lockfileVersion 2 and 3 - #16071

Open
Marukome0743 wants to merge 1 commit into
dependabot:mainfrom
Marukome0743:bun-lockfile-version-2-and-3
Open

Marukome0743 wants to merge 1 commit into
dependabot:mainfrom
Marukome0743:bun-lockfile-version-2-and-3

Conversation

@Marukome0743

Copy link
Copy Markdown

What are you trying to accomplish?

Fixes #16026.

Bun 1.4.0 writes bun.lock lockfileVersion 2 by default (oven-sh/bun#31539), and 3 for projects that use nested or version-scoped overrides (oven-sh/bun#38333). The updater image bundles bun 1.3.14, which reads only v1.

#15896 stopped bun silently downgrading those lockfiles, by rejecting anything above MAX_SUPPORTED_LOCKFILE_VERSION with DependencyFileNotSupported. That was the right trade at the time, but it means every repository that has regenerated its lockfile with 1.4 now gets no bun updates at all — the state reported in #16026. Reproduced against a real repository with a v2 lockfile:

=> parsing dependency files
An error occurred: Dependabot::DependencyFileNotSupported,
Unsupported bun.lock 'lockfileVersion' 2 in /bun.lock. The bun version Dependabot runs supports up to 1.

This is the follow-up #15896 said it would need: "at bun 1.4 GA, ARG BUN_VERSION and MAX_SUPPORTED_LOCKFILE_VERSION must be bumped together."

  • ARG BUN_VERSION 1.3.14 → 1.4.0
  • MAX_SUPPORTED_LOCKFILE_VERSION 1 → 3
  • The unsupported_lockfile_version fixture moves to v4 so the guard still guards, and simple_v2 / simple_v3 fixtures cover the two formats that are now accepted.

Anything you want to highlight for special attention from reviewers?

The ceiling is 3, not 2. 1.4's default is 2, but a project using nested ({"node-fetch": {".": "1.7.3", "encoding": "0.1.13"}}) or version-scoped ({"ansi-styles@^4.1.0": "4.2.1"}) overrides gets 3, and the lockfile grows a top-level overrides object. Stopping at 2 would leave those repositories broken in exactly the way #16026 describes. Measured with 1.4.0:

lockfile written by plain project nested / version-scoped overrides
bun 1.3.14 1 1 (overrides silently dropped)
bun 1.4.0 2 3

No parser change is needed. v1 and v2 lockfiles generated from the same manifest are byte-identical apart from the version number — the packages tuple shape is unchanged. v3 only adds the overrides object, which BunLock#dependencies ignores; simple_v3 is a real 1.4.0-generated lockfile that covers it.

This does not churn anyone's lockfile format. bun 1.4 leaves an existing v1 lockfile at v1 through both install and add, and still upgrades v0 → v1 exactly as 1.3.14 did. Running the updater's own command inside the new image against a real v2 lockfile leaves it at v2:

$ bun install --save-text-lockfile --ignore-scripts   # bun 1.4.0, image-bundled
  "lockfileVersion": 2,      # unchanged

A behaviour change reviewers should know about, deliberately not addressed here. In 1.4, bun update <name> re-resolves transitive packages within the parent's range instead of hoisting the dependency to the top level. For a transitive ansi-styles behind chalk@4.1.0 (^4.1.0):

resulting lockfile package.json
bun 1.3.14 ansi-styles@7.0.0, outside the parent range gains "ansi-styles": "^7.0.0"
bun 1.4.0 ansi-styles@4.3.0 untouched

SubdependencyVersionResolver#run_bun_updater keeps only the lockfile and discards the manifest, so today it can emit a lockfile pinning a version the manifest never asked for. 1.4 fixes that, but it changes which version subdependency updates land on. The existing spec stubs run_bun_command entirely, so CI does not exercise this either way; I left it alone rather than widen this PR.

Also out of scope: in 1.4 a project's bunfig.toml takes precedence over .npmrc for the same key (oven-sh/bun#38333), which can affect repositories relying on the .npmrc that FileUpdater::NpmrcBuilder writes for private registry credentials. Happy to file that separately if you'd like it tracked.

No github/docs PR. supported-package-managers.md lists Bun as >=v1.1.39 and does not name the bundled version, so the documented support range is unchanged.

How will you know you've accomplished your goal?

All of the below ran inside ghcr.io/dependabot/dependabot-updater-bun built from this branch (bun 1.4.0).

  • bun suite: 383 examples, 0 failures. As a control, the suite at HEAD (ceiling 1, spec/fixtures unchanged) against the same bun 1.4.0 image is 381 examples, 0 failures — so the binary bump alone causes no regression, and this branch only adds the two new examples.
  • The guard still guards. unsupported_lockfile_version is now v4, so the DependencyFileNotSupported example still fails if the ceiling is raised past 3. Conversely, the new simple_v2 / simple_v3 examples fail with the old ceiling of 1, so they exercise the change rather than passing incidentally.
  • End to end. bin/dry-run.rb bun <repo> against a repository with a v2 bun.lock fails at "parsing dependency files" with the error quoted above before this change, and completes ("Dry-run completed successfully", 29 dependencies checked) after it.
  • rubocop clean on bun/lib and bun/spec. bun/spec/ is excluded from sorbet/config, and the only production change is an integer constant and its comment.

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

Bun 1.4 writes lockfileVersion 2 by default, and 3 for projects that use
nested or version-scoped overrides. The updater image bundles bun 1.3.14,
which reads only v1, so since dependabot#15896 the parser rejects those lockfiles with
DependencyFileNotSupported and updates stop entirely for any repository that
has regenerated its lockfile with 1.4.

Bump the bundled bun to 1.4.0 and raise MAX_SUPPORTED_LOCKFILE_VERSION to 3
in lockstep, the follow-up dependabot#15896 said would be needed at 1.4 GA.

v1 and v2 lockfiles are identical apart from the version number, and bun 1.4
leaves an existing v1 lockfile at v1, so repositories that update cleanly
today keep their current lockfile format.
@Marukome0743
Marukome0743 requested a review from a team as a code owner August 28, 2026 02:07
@v-kbukum1 v-kbukum1 moved this to Scoping in Dependabot Sep 14, 2026
pathosDev added a commit to pathosDev/actor-ts that referenced this pull request Sep 20, 2026
…t writes its lockfile

The repository tracks thirteen package.json manifests and `.github/dependabot.yml`
watched one of them — the root, through the `npm` ecosystem, which has no code
for `bun.lock` at all (`npm_and_yarn/` in dependabot-core does not mention it)
and therefore ran manifest-only.  A caret range already admits every minor and
patch, so an in-range release changed nothing that updater could see: the
`npm-minor-and-patch` group configured since `b5464448` opened no PR in five
months, and every root PR Dependabot did open (thirteen, #29 to #908, all
majors) edited `package.json` alone and went red on every frozen install until
`bun.lock` was regenerated by hand (#817).  The other twelve manifests got
security updates only — Dependabot opens those from the dependency graph
regardless of this file, which is what the `npm_and_yarn group across N
directories` PRs are — and were kept current by hand (#1520).  #779 is what the
blind spot cost: all nineteen high advisories in the runtime closure were fixed
inside the declared ranges, exactly the updates that never surfaced.

The ecosystem now follows the lockfile CI installs from:

- `package-ecosystem: "bun"` for the five Bun-installed manifests — `/`,
  `/docs`, `/devtools-ui`, `/benchmarks/comparison`,
  `/tests/integration/brokers`.  Its updater runs `bun install <dep>@<version>
  --save-text-lockfile` and commits the result, so a PR arrives green on
  `--frozen-lockfile` and in-range updates surface as the grouped daily PR.
  One entry per directory, deliberately not a `directories:` list: a grouped
  update across directories is a single PR, and the DevTools UI half of it is
  red by construction — `bun run check:ui` hashes `devtools-ui/package.json`
  into the embedded bundle's `source-hash`, so a bump there needs `bun run
  build:ui` in the same merge, like any change under `devtools-ui/` — which
  must not hold a root or docs bump hostage.  Neither updater reads
  `peerDependencies` (`DEPENDENCY_TYPES` in both parsers), so no peer floor
  moves as a side effect.
- `package-ecosystem: "npm"` with a `directories:` list for the eight example
  frontends, because `examples.yml` builds them with `npm ci` from
  `package-lock.json`.  The `bun.lock` each also carries is #1402's open
  decision; until then the dry-run leg there goes red on the directories a PR
  touches, naming the lockfile to sync.  A minor-and-patch group spans the
  eight (one PR a day, not eight) and a `group-by: dependency-name` group
  lands a major in both halves of a chat/voice pair at once.

The Dependabot bun updater bundles Bun 1.3.14 and, since
dependabot/dependabot-core#15896, refuses a `lockfileVersion` above 1 with
`DependencyFileNotSupported` — no PRs, no silent downgrade;
dependabot/dependabot-core#16071 raises the ceiling and is still open.  Bun 1.4
stamps a fresh lockfile 2 but preserves an existing 1 on every re-save, so the
four lockfiles born under 1.3 are fine and `devtools-ui/bun.lock`, born under
1.4.0 as a 2 (`65548aa9`), is restamped to 1.  The content is identical (v2
only added parse-time strictness), and measured rather than assumed: under
1.4.2 a frozen install of the restamped file succeeds (352 packages) and an
unfrozen one — what `ui:install` runs — reports no changes, both leaving the
file byte-identical.

`tests/unit/ci/WorkflowHygiene.test.ts`, which already parses this file, now
lists every tracked package.json from the git index and asserts that each is
named by exactly one `bun`/`npm` entry, that the entry's ecosystem is `npm`
iff a `package-lock.json` sits beside the manifest, that every directory an
entry names holds a manifest, and that every `bun.lock` a `bun` entry watches
carries a stamp the updater reads.  Each assertion was checked to fail on the
mutation it exists for: an entry removed, an ecosystem crossed, a directory
that does not exist, a directory named twice, the lockfile restamped to 2.

Also: commit prefixes are `chore` + Dependabot's own scope, so messages read
`chore(deps): …` / `chore(deps-dev): …` — the two scopes AGENTS.md lists —
instead of the doubled `chore(deps)(deps-dev): …` the old prefix produced; and
the header no longer says PRs open against `main` (they target `develop`).

Closes #1596

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alrayyes added a commit to alrayyes/washy-washy-pdf that referenced this pull request Sep 25, 2026
…e it

Same cause as hush-hush-action#28: Dependabot's bundled bun binary
only supports bun.lock lockfileVersion 1; this repo's lockfile is
lockfileVersion 2 (what bun 1.4+ writes by default), so every weekly
bun update fails before it even looks at what needs updating.

Tracked upstream as dependabot/dependabot-core#16026, with a fix open
as dependabot/dependabot-core#16071 but not merged. Commenting the
entry out rather than deleting it so it's a one-line uncomment once
that lands.

Closes #113
alrayyes pushed a commit to alrayyes/washy-washy-pdf that referenced this pull request Sep 25, 2026
## [2.4.5](v2.4.4...v2.4.5) (2026-09-25)

### Bug Fixes

* **deps:** pause bun ecosystem in dependabot.yml, upstream can't parse it ([9b7ca80](9b7ca80)), closes [dependabot/dependabot-core#16071](dependabot/dependabot-core#16071) [#113](#113)
tarioto added a commit to tarioto/winchester-storage that referenced this pull request Oct 1, 2026
Bun 1.4 writes bun.lock lockfileVersion 2, but Dependabot's bun updater
bundles Bun 1.3.14 and only reads version 1, so every bun update job
fails. Pin packageManager to 1.3.14 and convert the lockfile back to
version 1 (resolved versions unchanged apart from one deduped nested
aria-query).

Bun 1.3's dev server ignores the path public-files.ts returns for
externals and links public/ assets by absolute project path, so dev.ts
now maps those requests back to public/.

Unpin once dependabot/dependabot-core#16071 ships.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@luizsignorelli

Copy link
Copy Markdown

thanks for working on it @Marukome0743. We just moved to bun 1.4 and would be nice to have dependabot working

PunGrumpy added a commit to PunGrumpy/vecstore-sdk that referenced this pull request Oct 3, 2026
* chore: ignore agent worktrees so the local lint run passes

Each worktree inside the checkout has its own oxlint config and its own
node_modules. oxlint loads every nested config, and the second copy of the
anti-slop plugin stops the run with "Plugin name 'anti-slop' is already
registered". That makes bun run check fail in any checkout that holds a
worktree.

oxlint and oxfmt skip any path that .gitignore lists, so this entry removes
the worktrees directory from both. The entry names only that directory, so
the tracked settings and skills files beside it stay visible.

* ci: keep bun.lock at the lockfile version dependabot reads

Dependabot's bun updater rejects lockfileVersion 2, and every bun update run
has failed since 2026-09-18. This sets bun.lock back to version 1 and adds a
step to the lint job that fails when the version changes. Remove the step
when dependabot/dependabot-core#16071 ships.

* chore(deps): apply bun audit fix for next and brace-expansion

GHSA-vcvr-r3jv-pc5j is a critical remote code execution bug in the next/og
ImageResponse. It affects next 16.3.5, and 16.3.6 fixes it. The docs site does
not import next/og, so no site code calls the affected API, and the bump needs
no code change.

brace-expansion moves from 1.1.18 to 1.1.21 and from 5.0.9 to 5.0.12, which
clears its advisories.

The undici advisories remain. The newest @qdrant/js-client-rest, 1.19.0, pins
undici 7.29.0 exactly, so the fix waits for a new release of that package. The
braces advisory GHSA-vfj7-8cjw-p6xm also remains because braces has no
published fix.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Scoping

Development

Successfully merging this pull request may close these issues.

Bun 1.4 uses lockfile v2 which dependabot currently does not support

3 participants