Dashboard hides individual retry when an upload fails before its first progress event
AI authorship and provenance
This report was generated by GPT-6 Astra, an AI assistant, based on the investigation of a real-world regression found while upgrading an application from Uppy 3 to Uppy 6. The investigation also uncovered this conditional retry control regression. The report distinguishes the real HTTP observation from the synthetic no-progress reproduction below.
The example contains only public Uppy APIs and synthetic data. No application-specific implementation, endpoints, credentials or data are shared.
Summary and evidence boundary
If a file fails before any upload-progress event, Dashboard can omit the individual file retry control, while retaining the footer Retry button. The first failing released combination found is Core 4.3.1 + Dashboard 4.1.3, included in uppy 4.9.0.
This condition is reproduced deterministically with a synthetic uploader. In the separate real HTTP 422 validation test, progress had reached 100% and the individual retry icon was present. We have not reproduced this missing-control condition with an actual HTTP server response, established its frequency in real uploads, or tested the exact mismatching-file validation scenario. The evidence does not support claiming that ordinary HTTP 422 responses generally lose retry.
Link to runnable example
https://jsfiddle.net/tagliala/y917v0dg/1/
This is a single HTML document. It loads unmodified, version-pinned, prebuilt
uppy JavaScript/CSS bundles from jsDelivr into separate iframes. No account,
server, selected file, framework or build step is required.
Steps to reproduce
- Open the fiddle. The comparison runs automatically on load.
- Select Retry icon: last good / first bad / current from the Compare dropdown (this is the default selection). Changing the selection reruns the comparison automatically. The Run / reset comparison button can also force a reset.
- Leave Emit progress before failing unchecked.
- Wait for the synthetic uploads to fail and the JSON results to appear:
[email protected]: the individual retry icon is present.[email protected]and[email protected]: it is missing.- The footer Retry control remains present in all three.
- Enable Emit progress before failing and wait for the comparison to rerun. The individual retry icon is now present in all three versions.
- Click an individual retry icon where present, or the footer Retry button otherwise. The synthetic uploader succeeds on its second attempt.
The uploader emits upload-start, optionally upload-progress, and then
upload-error with a synthetic error. It does not manually unset
progress.percentage, replace the Dashboard, or patch Uppy internals.
Expected behavior
A failed file should retain its retry action even if its progress percentage is unknown. Suppressing an unknown progress indicator should not suppress the error recovery action.
This expected behavior is supported by earlier releases and by the existing
retry-rendering branch in FileProgress. Whether any specific upload error
should be retried remains a separate application concern.
Actual behavior
With no progress event before failure:
| uppy bundle | Core | Dashboard | Progress percentage | Individual retry | Footer retry |
|---|---|---|---|---|---|
| 4.1.0 | 4.1.0 | 4.0.2 | 0 | Present | Present |
| 4.8.0 | 4.3.0 | 4.1.3 | 0 | Present | Present |
| 4.9.0 | 4.3.1 | 4.1.3 | undefined | Missing | Present |
| 6.0.1 | 6.0.1 | 6.0.0 | undefined | Missing | Present |
The demo displays an undefined percentage as JSON null. The file is in an
error state in every row. With a progress event before failure, all these
versions show the individual retry control and report 50% progress.
The footer action remains usable, so the reproduction does not demonstrate a complete loss of retry functionality. The incorrect Uploading heading visible in these versions is a separately investigated regression with an earlier version boundary.
Screenshot
Confirmed release boundary and source analysis
1. A pre-existing Dashboard guard
Dashboard - convert some files to typescript — PR #5359,
commit 18cd1db114,
introduced this check in FileProgress, before the failed-file retry branch:
if (props.file.progress.percentage === undefined) {
return null
}It shipped in Dashboard 4.0.2 on 2024-07-30. That is not by itself the first
failing release for this reproduction: the [email protected] bundle contains that
Dashboard version and still shows the icon because Core initializes zero.
2. Core stops initializing progress to zero
Companion stream upload unknown size files — PR #5489,
commit 24fd4158a9,
removed percentage: 0 from Core's upload-start state. Until a progress event
arrives, the percentage is then undefined, including for the synthetic file of
known size used here.
Combined with the Dashboard guard, this suppresses the retry branch on failure.
- Last good: Core 4.3.0 / uppy 4.8.0, published 2024-12-05.
- First bad: Core 4.3.1 / uppy 4.9.0, published 2024-12-17.
- Dashboard stays at 4.1.3 across this boundary.
Component versions were read from the running prebuilt bundles, not inferred
from semver ranges. Git ancestry separately confirms the Core commit is absent
from [email protected] and present in [email protected].
Relevant source at the checked main revision:
Candidate fix for maintainers to assess: handle failed-file retry before
the unknown-percentage guard, preserving the intended handling of genuinely
unknown progress. Suggested tests should include failures before/after progress,
hideRetryButton, and recovery through both available controls. This candidate
has not been implemented or validated by this report.
Unreleased main and existing reports
Checked canonical transloadit/uppy on 2026-09-13 at main commit
49199f24c2a57a88aada504dabb17cc5dcf19afe.
FileProgress/index.tsx is identical by Git blob hash to Dashboard 6.0.0;
Uppy.ts is identical to Core 6.0.1. XHRUpload's index.ts is also identical to
6.0.0. No unreleased fix was found in these controlling paths. Main was
source-reviewed, not browser-built.
Searches for retry icons/buttons and undefined progress, including issue comments, found no matching current report or corrective PR. Retry icon no longer shows on each file — issue #1881 is a closed 2019 report with a similar symptom. A maintainer described that older behavior as unintentional, but it predates both commits above; we are not asserting it is the same bug or that maintainers are unaware of this one.
Verification and limitations
- Chromium 153.0.8010.12, macOS arm64, driven by Playwright 1.63.0.
- The human reporter also manually checked the reproduction in Firefox 155.0.1 (aarch64) and Safari 26.6.2 (21624.5.1.11.3). These are reporter-provided manual checks, not additional AI-run automation.
- Eight released bundles were tested with and without a progress event: 16 version/progress combinations.
- Retry recovery succeeded in all 16, using the individual control whenever available and otherwise the footer control.
- The demo uses a synthetic uploader registered through
addUploaderand normal Uppy lifecycle events. It isolates Core/Dashboard behavior and does not exercise XHR, CORS, server validation, real network timing or network failure frequency. - The real HTTP 422 observation retained its individual retry icon at 100% progress. No claim is made that this conditional missing icon occurs for every validation error or for the exact mismatching-file scenario.
- Automated verification used the local standalone HTML. The reporter published the linked fiddle and supplied the Firefox/Safari checks above. The AI did not independently rerun those manual checks or the hosted result. The 16-case automated matrix is specific to Chromium.
Related report
Separate failed-upload heading regression. The two reports share the same standalone reproduction but have different release boundaries and evidence.
Source: transloadit/uppy