fix(cli): share injected source pairs between process inject and upload - #91427
Merged
Conversation
|
😎 Merged successfully - details. |
Contributor
🤖 CI report✅ Trunk lane — non-backend laneThis PR is assigned to the non-backend lane. It does not run backend Python tests and may merge in parallel with PRs in other lanes. |
1 task
cat-ph
marked this pull request as ready for review
August 31, 2026 18:58
Contributor
pr-assigner-resolver-posthog
Bot
requested review from
a team,
ablaszkiewicz and
hpouillot
August 31, 2026 18:58
Contributor
Prompt To Fix All With AI### Issue 1
cli/src/commands.rs:424-429
**Comments preserve change history**
These comments contrast the new handoff with the former directory walk and cite the originating regression, with the same history repeated in `plain/upload.rs` and `source_pairs.rs`. Repository guidance reserves that context for the PR or commit message; keeping it in the implementation creates stale commentary that obscures the current invariant.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(cli): harden delete-after cleanup ag..." | Re-trigger Greptile |
ablaszkiewicz
approved these changes
Aug 31, 2026
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Problem
posthog-cli sourcemap processcan abort a user's production build withChunk ID not found(exit 1) when something writes into the scanned directory while the command runs. Next.js 16.3+ users hit this on every build: Turbopack's filesystem cache (on by default there) keeps flushing files into.nextin the background while@posthog/nextjs-configruns the CLI, reported in posthog-js#4667.The cause is a time-of-check/time-of-use race inside
process: the inject pass and the upload pass each walk the directory roots and read the files independently. A chunk pair that materializes (or changes) between the passes reaches upload without an injected chunk ID, and one such pair fails the entire upload.This PR is an alternative to #91191 (path-snapshot approach). Review on that PR surfaced three semantic gaps the snapshot needs shims for: upload re-reads contents so an overwritten chunk still aborts, inject re-validates existence of every snapshotted path so a concurrently deleted cache file aborts, and deriving cleanup roots from snapshot entries narrows the
--delete-aftersafety guard under--include/--exclude. This PR removes the whole class instead: land one of the two, close the other.Changes
processnow reads the source pairs from disk once, injects them, and uploads those same in-memory pairs. There is no second directory walk and no re-read, so a build no longer fails when files appear, change, or vanish mid-run, and upload sends exactly the bytes inject stamped.--delete-aftercleanup keeps deriving its safety roots from the original selection, so its authorization scope is unchanged.Chunk ID not founderror now names the offending file and says how to recover.--delete-aftercleanup no longer fails the build after a successful upload when a file vanished or was replaced mid-run: every artifact is fingerprinted when read, and cleanup only strips or deletes what still matches - through the verifying file handle for sources, and via an atomic rename-verify-remove for maps. Skipped files warn instead of aborting, a map shared by several chunks is only deleted once every source referencing it verified, and read-only sources that need no stripping no longer require write access.injecting selectionlog line is bounded by entry count and byte budget. A large stdin-provided selection used to render as one ~1 MB line, which killed the CLI with EAGAIN when stderr was a non-blocking pipe (e.g. spawned from Node.js with inherited stdio).inject_implandplain::inject::injectreturn the injected pairs; upload is split intoupload(walks, standalone command) andupload_pairs(consumes given pairs); standalonesourcemap inject/sourcemap uploadbehavior is unchanged.How did you test this code?
inject_impl_returns_the_injected_pairs: injects a fixture pair and asserts the returned in-memory pair carries a chunk ID and matches the bytes written to disk — the propertyupload_pairsrelies on. The freeze itself is structural: upload consumes the pairs it is given and cannot see later files.display_is_bounded_for_large_selections,display_is_bounded_for_long_paths, anddisplay_truncates_a_single_oversized_pathpin the log-line byte bound.--delete-afterhardening: happy path, missing source, replaced source, replaced map, shared map with a skipped source, shared map matching any uploaded copy, and overlapping-roots dedupe.cargo testfor the CLI crate,cargo clippy --all-targets, andcargo fmtare green locally.next buildagainst a live PostHog instance with this CLI build.Automatic notifications
Docs update
Sampo changeset included (
cli/.sampo/changesets/sourcemap-process-shared-pairs.md); no docs describe the process internals.🤖 Agent context
Autonomy: Human-driven (agent-assisted)