Skip to content

chore: recover from the Rekor 409 that keeps failing releases - #408

Merged
gregberge merged 1 commit into
mainfrom
claude/release-failure-investigation-2ec960
Oct 21, 2026
Merged

gregberge merged 1 commit into
mainfrom
claude/release-failure-investigation-2ec960

Conversation

@gregberge

Copy link
Copy Markdown
Member

Description

The last two releases failed on the same provenance error:

TLOG_CREATE_ENTRY_ERROR error creating tlog entry - (409) an equivalent entry already exists in the transparency log
  • Run 39601015349 (today): @argos-ci/cypress@7.4.0 was not published. The other 7 packages were.
  • Run 38902693584 (Oct 16): @argos-ci/browser@6.5.1 was not published, and lerna skipped every package that depends on it.

This is the retry-after-success described in #364:

  1. Rekor saves the entry but replies after Sigstore's 5s timeout.
  2. Sigstore resubmits the same entry, and Rekor answers 409 because it already has it.
  3. Sigstore hardcodes fetchOnConflict: false, so the 409 is fatal. Upstream issue: Recover Rekor duplicate-entry conflicts by default sigstore/sigstore-js#1708. It's still hardcoded in sigstore 5.0.0.

The timing matches: each failure lands about 7.5s after the previous publish, which is one 5s timeout plus the retry backoff. #366 showed the timeout can't be raised through lerna, and named this patch as the proper fix.

Changes

  • Patch sigstore@4.1.1 (patches/sigstore@4.1.1.patch): one line, fetchOnConflict: true. On a 409, Sigstore fetches the existing entry using the Location header and uses it. That entry is the one our first attempt wrote, because Rekor only calls an entry "equivalent" when it has the same signature and key. The patch is registered in pnpm-workspace.yaml with a comment. If an upgrade removes sigstore@4.1.1 from the dependency tree, pnpm errors on the unused patch, so someone has to look at it again.
  • New from-package release type (workflow option, release-from-package script, RELEASING.md). It runs lerna publish from-package. A failed release has already tagged the packages and created their GitHub releases, so a normal rerun finds nothing to bump and @argos-ci/cypress@7.4.0 would never ship. This publishes only the versions that npm is missing.

Testing

  • Rekor 409: I ran Sigstore's real Rekor client against a mock Rekor that saves the first POST, replies after 6s and answers the retry with 409.
    • Stock sigstore fails with TLOG_CREATE_ENTRY_ERROR, as in CI.
    • The patched copy sends POST, POST, GET /api/v1/log/entries/<uuid> and builds the bundle.
  • Patch install: lerna → libnpmpublish loads the patched copy, and pnpm install --frozen-lockfile accepts the patch.
  • from-package: I ran lerna publish from-package --yes on a checkout of main against a mock npm registry on localhost, so nothing reached npm. It reported Found 1 package to publish: @argos-ci/cypress => 7.4.0, sent only that one, and created no commit or tag.
  • Not tested: the real Fulcio/Rekor path. Only the next real release will exercise it.

After merge

Dispatch Release with release type from-package to publish @argos-ci/cypress@7.4.0. All other package versions on main are already on npm. @argos-ci/cypress@7.3.0 from Oct 16 was never published either, but 7.4.0 replaces it.

Type of changes

bug

Checklist

  • The commits message follows the Conventional Commits' policy
  • My changes requires a change to the documentation
  • I have updated the documentation accordingly (RELEASING.md)

🤖 Generated with Claude Code

The last two releases died on the same provenance error:

  TLOG_CREATE_ENTRY_ERROR error creating tlog entry - (409) an equivalent
  entry already exists in the transparency log

Run 39601015349 lost @argos-ci/cypress@7.4.0. Run 38902693584 lost
@argos-ci/browser@6.5.1, and with it every package that depends on it.

It is the retry-after-success from #364. Rekor commits the entry but
answers after sigstore's 5s timeout, sigstore resubmits it, and Rekor
deduplicates with a 409. sigstore hardcodes `fetchOnConflict: false`, so
the 409 is fatal (sigstore/sigstore-js#1708, still the case in 5.0.0).
The timing matches: each failure lands ~7.5s after the previous publish,
one 5s timeout plus retry backoff. #366 showed the timeout cannot be
raised through lerna, and called this patch the proper fix.

- Patch sigstore@4.1.1 to set `fetchOnConflict: true`. On a 409 it reads
  the existing entry from the Location header and uses it, which is the
  entry the first attempt wrote. Against a mock Rekor that commits the
  first POST, replies after 6s and 409s the retry, stock sigstore fails
  with TLOG_CREATE_ENTRY_ERROR and the patched one builds the bundle.
  lerna's libnpmpublish resolves the patched copy.
- Add a `from-package` release type running `lerna publish from-package`.
  A failed release has already tagged and created the GitHub releases, so
  a normal rerun sees nothing to bump and 7.4.0 would never ship. Against
  a mock registry, it picked only @argos-ci/cypress@7.4.0 on `main` and
  left no commit or tag behind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
argos-js-sdk-reference Ready Ready Preview Oct 21, 2026 1:06pm UTC

Request Review

@gregberge
gregberge merged commit cfcee2c into main Oct 21, 2026
105 of 106 checks passed
@gregberge
gregberge deleted the claude/release-failure-investigation-2ec960 branch October 21, 2026 13:11

This branch was successfully deployed

1 active deployment
Preview — c104757a Deployed Oct 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant