Hive
fix(server): give each build-processing job a unique download path
GitHub issue · Closed
Symptom
Sentry TUIST-10H: ProcessBuildWorker failed with
{:error, "The line lications/Xcode.app/C doesn't seem like a valid SLF line"}
It looks like a corrupt xcactivitylog, but it isn’t.
Root cause — verified against the real artifact
I pulled the actual archive (Notion build 8fce77ae) and confirmed:
- The xcactivitylog is valid — it parses cleanly with XCLogParser
0.2.48(the exact version prod resolves, byte-identical to the registry source) on macOS, stock Linux, and a faithful reconstruction of the proddebian:bookworm-slimruntime. gzip intact, 0 NUL bytes. - The build was processed successfully: the
build_runsrow hasstatus=success,duration=4658, inserted at 07:27:22.091 — ~1 second before the 07:27:23 error.
A success written before the error means two jobs ran concurrently for the same build (the get_or_create_build duplicate-enqueue race that Oban uniqueness only mostly absorbs). Both download to Path.join(System.tmp_dir!(), "build_#{build_id}.zip") — a path keyed only on build_id. One job’s download (or its File.rm cleanup in the after block) overwrites/deletes the archive the other job is still unzipping, so the victim parses a truncated/garbage local copy and throws invalidLine. The artifact in storage is fine; only the shared temp file was corrupted.
This explains why it’s a single self-healed occurrence, why it can’t be reproduced standalone, and why it’s neither a corrupt file nor an XCLogParser bug.
Fix
Add a per-execution System.unique_integer/1 to the temp download path so concurrent jobs for the same build never share a file. The unzip directory was already unique (make_temp_dir); only this download path was shared.
Test
TDD: a new test invokes perform/1 twice for the same build and asserts the two download paths differ. Red against the shared-path code, green after the fix. Full worker suite passes; mix format / mix credo clean.
🤖 Generated with Claude Code
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
No GitHub comments yet.