## TL;DR

When parallel workers all write to the same JUnit XML file, the last writer wins and the rest of the results vanish. Give each worker its own report file (worker id in the filename), then merge the files after the run with a JUnit merge tool. One file per worker, one merged report at the end.

## Error

```text
agent's parallel workers overwrote each other's junit reports: how to merge
```

Four workers, one report path: the final XML contained only the last worker's results, and the dashboard showed a fraction of the suite.

## Steps

1. Confirm the overwrite: check the report file's test count against the suite's test count. Expected output: a shortfall proving results were lost.
2. Change the runner config so each worker writes its own file, with the worker id in the filename. Expected output: N complete per-worker XML files.
3. Add a merge step after the run that combines the per-worker files into one report (junit merge tooling or the runner's built-in merge). Expected output: a single XML with every test exactly once.
4. Validate the merged report: total test count matches the suite, no duplicates, no missing tests. Expected output: a count check that passes.
5. Point dashboards and the agent at the merged report only; archive the per-worker files. Expected output: one source of truth downstream.

## When to use

- Parallel runs produce incomplete JUnit reports.
- Test counts in the report do not match the suite.
- An agent set up parallelism and kept a single report path.

## When not to use

- Single-worker runs (one file is correct).
- The runner already shards reports natively (use its mechanism, not a custom one).
- You only need pass/fail per worker, not a merged report (then aggregate counts, not XML).

## Variant phrasings

### Workers appended to the same file and corrupted the XML

Appending XML is not merging. Same fix: separate files, then a real merge.

### Sharded runs each uploaded their own report and the dashboard double-counted

The mirror problem: merge before upload, or upload shards with shard ids and dedupe downstream.

### Agent merged reports with a text-concat script

Concatenated XML is invalid XML. Use a real JUnit merge.

## Why it happens

The report path is configured once for the suite, and parallelism gets bolted on later. Each worker opens the same path for writing because nobody told it otherwise. The failure is silent: the XML is valid, just incomplete, so it looks fine until someone counts.

## Edge cases

- Workers that crash may leave partial XML; the merge step should tolerate or flag malformed shard files.
- Duplicate test ids across shards (same test run twice) need dedup rules in the merge; decide whether first or last wins.
- Timestamps across workers can confuse duration-based flake detection; normalize or annotate with worker ids.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_hoj_pHEeQeI2JBNdbjNVCQ
