Skip to content

archiver: one bad stem fails the entire archive (sizing and download are both all-or-nothing) #83

Description

@dylanjeffers

Summary

A single bad stem fails the entire archive. Two all-or-nothing points in processJob (src/workers/createStemsArchive/createStemsArchive.ts):

const fileSizes = await Promise.all(stems.map(inspectFileSize))   // throws if any stem has no size
...
downloadedFiles = await Promise.all(downloadPromises)             // one rejection fails the job

inspectFileSize throws when inspection.data?.size is falsy, so the job can die during sizing — before a single byte is downloaded — because one stem's metadata is incomplete.

Context

#75 already made the parent track best-effort for exactly this reason: a broken or missing original shouldn't hold hostage the stems the user actually asked for. Stems themselves never got the same treatment.

This matters because content-node availability is genuinely flaky. Sampling all 11 stems of one contest track across 3 rounds on 2026-07-28, 1–2 canonical hosts returned 502/503/521 each round (audius-nodes.com, cn0/cn2.mainnet.audiusindex.org). The creatornode.audius.co fallback recovered every one of them in that sample — but the margin is thin, and with no per-stem retry a single stem that fails both its canonical host and the fallback loses the whole archive.

Related: the mirror list is always empty in practice (the pinned @audius/sdk 10.0.0 deserializer drops the download/stream fields the API returns), so each stem effectively gets 2 attempts, not 5. #76 fixed the symptom by trying the canonical host first; the underlying "no mirrors" cause is still there.

Proposed fix

Give stems the #75 treatment — deliver what resolved, and include a manifest (or filename convention) listing what was skipped and why, so the user knows the archive is partial rather than silently receiving fewer files. Fail the job only when no stem could be retrieved.

Worth considering alongside: per-stem retry, and fixing the empty mirror list so there are more than two candidate hosts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions