The upload says 100%. Why is the attachment missing?
A file reaches 100%, yet submission says no attachment is present. I would first agree on what completion means, before changing the progress bar. Using a fictional workshop proposal, this article separates transfer, validation, replacement and submission, then turns those decisions into a specification and QA handoff.
Start with the meaning of complete
A progress indicator initially looks like the answer to an unexplained wait. But if someone submits at 100% and the file is absent, the issue is the point at which they believed the job was done. Check whether choosing a file, sending its bytes, confirmed server receipt and passing validation have been given the same label.
The fictional service requires one workshop proposal PDF, no larger than 10MB, with no empty or password-protected files. Here 10MB means exactly 10,000,000 bytes. Other proposal fields remain in the form. These are example constraints. For a real service, first document why reviewers need the PDF and whether you are asking people to upload information already collected elsewhere.
Follow one file through the screen and server
“Attachments sometimes fail” leaves too much to rediscover. Put file selection, the 100% display, receipt and validation on one timeline. Use newly created test files. Link the displayed name to the identifier the server assigns that attachment, so different content with an identical filename remains distinguishable.
GOV.UK informs the need-for-upload check and specific error guidance. OWASP supports server-side content and permission checks rather than trusting an extension or supplied type. That changes the proposed design: the completion label should follow confirmation that the currently selected file is usable, not merely the progress indicator reaching its end.
Capture the UI, response time and result for the same attempt.
| Sequence | UI evidence | Engineering comparison |
|---|---|---|
| Choose file | Name, size and selection time | Selection-to-attempt association |
| Reach 100% | Any misleading completion text | Whether receipt is confirmed |
| Validate | Pending, rejected or unknown result | Validation state and attachment identifier |
| Before submission | Currently displayed attachment | Actual file associated with the application |
Choose the completion rule before the button state
Showing a filename immediately is useful, provided the list does not imply completed attachments. One option enables submission at 100%; it appears fast but may precede receipt or validation. The second separates transfer and checking, enabling submission only after server confirmation. I would choose the second for this example.
Hiding everything until the end is another option, but it makes recovery harder when a file fails. Show the name early with its state. If validation is not available yet, do not ship a screen that pretends it is: agree on what the server can actually confirm and reduce scope. Keep the reason in the proposal and the response conditions in the specification.
A visible filename is not permission to submit.
| Option | Remaining problem | Example decision |
|---|---|---|
| Complete on selection | Bytes may not have been sent | Reject |
| Complete at 100% | Receipt and validation may be unknown | Use only as progress |
| Complete after server confirmation | Needs pending, rejected and unknown states | Chosen design |
Pending validation differs from an unknown result
At 100%, unknown server receipt means “Confirming transfer.” Confirmed receipt with validation still pending means “Checking file.” Neither allows submission, but they point to different checks. Oversize files need a smaller replacement; an unresponsive checker does not justify telling someone their file is defective.
A completion response must belong to the current selection and upload attempt. Require its server attachment identifier, proposal association and validation pass before showing “Attachment complete.” Compare server status versions too: an old checking response must not regress a newer completed state for the same attempt. This connects the UI specification to concrete backend guarantees and testable response ordering.
Example copy; preserve the other proposal inputs.
| Known state | UI message | Next action |
|---|---|---|
| No file | Attach one PDF | Choose a file; cannot submit |
| Transferring | Transferring file · progress | Wait or remove |
| 100%, receipt unknown | Confirming transfer | Query the same attempt; cannot submit |
| Received, validation pending | Checking file | Wait or replace |
| File rejected | Example: Choose a PDF of 10MB or smaller | Correct or replace for the stated reason |
| Validation result unknown | We could not confirm the check result | Check status; do not blame file content |
| Current file passed | Attachment complete · filename | Submit if other requirements also pass |
A removed file must not return with a late response
If success arrives after someone removes a file under validation, adding it back would undo their action. Removal and replacement invalidate the old selection. Cancelling the native file picker changes nothing; actually choosing another file excludes the previous attachment. Even an invalid replacement must not silently restore the old file.
Identical names can contain different documents. Give the new selection a new version and attempt, and exclude the previous selection from server acceptance too. An abort request does not prove that received server bytes were deleted. UI removal, transport cancellation and temporary-file cleanup need separate records. Confirm the real temporary-file lifetime with operations and describe deletion only to the extent it is verified.
Evaluate each response. Ignoring an old response does not stop the current file.
Read the flow
- Current selection, attempt and latest state?
- Yes: Update current state with this result → Describe current state and next action
- No: Ignore old result; retain current selection → Describe current state and next action
Apply the same rules to retry and final submission
A broken connection does not prove the server missed the file. Query the original upload attempt first. Do not create a new transfer while it is processing. After confirmed failure or non-receipt, consider resending only if engineering has confirmed how the same content and attempt avoid duplicates. Without that contract, offer status checking and explicit new selection rather than automatic resending.
The submission server must not trust a client completion label. Recheck current ownership, proposal association, selection version and validation consistently with acceptance. Prevent attachment changes while acceptance is in progress. If its response is lost, query the same application identifier. An accepted application retains its own attachment independently of editing state. Post-acceptance replacement is outside this example and would need a separate change process.
Fixed design examples; no file is uploaded and no application is submitted.
Open the example
Receipt and validation pass are not confirmed. Progress alone cannot permit submission.
Ignore a late pass. Exclude the old selection from server acceptance as well.
This is a new selection. Old-file success cannot complete the new file.
Query the same application identifier. Do not create another application or change the attachment while the result is unknown.
Ask AI about conflicting sequences, not just success screens
A request for an upload specification may produce buttons and errors while missing the actual issue: does response reordering still submit the intended file? Supply the fictional constraints, completion rule, removal and replacement behavior. Ask for a table with the starting state and delayed response so omissions can be checked against the agreed rules.
If a response enables submission at 100%, revise that condition rather than accepting the whole answer. Separate unknown receipt from pending validation and add success after removal. Replace filename-only association with selection versions and server attachment identifiers. Leave actual server support for engineering confirmation, then carry the corrected rules into UI copy and QA. These are example review instructions, not an executed AI exchange.
Supply the decisions first, then vary response ordering.
Example prompt, not an executed AI conversation: Review one required PDF attachment for a fictional public workshop proposal. Allow one PDF of 1 to 10,000,000 bytes. Reject empty or password-protected files and require server content checks. 100% transfer is not attachment completion. If receipt is unknown, show Confirming transfer; after receipt but before validation finishes, show Checking file. Complete requires the current selection, matching upload attempt, server attachment identifier, proposal association and a usable validation result. A new file selection excludes the old attachment; cancelling the file picker alone changes nothing. Ignore late results after removal or replacement. The same name does not identify the same content. Unknown results are not confirmed failures: query the same attempt first. Confirm the server's deduplication contract before retrying the same content and attempt. Submission rechecks ownership, proposal association, current version and validation. List initial state, action, delayed response, UI text and whether submission is allowed. Mark unsupported or unspecified server behavior as requiring confirmation. Example correction: remove submission permission at 100%. Add removal during validation and replacement with a same-name file before an old success arrives. Preserve other proposal inputs and state which attachment the final request includes.
One successful small PDF is not enough QA
Test size boundaries and empty files, delayed responses and same-name replacements. Compare the expected attachment identifier with the one actually accepted: the correct filename can still refer to an old document. Reproduce interruptions and stale responses in a controlled test environment and record what happened, rather than relying on a normal-network screenshot.
W3C status-message guidance informs textual progress and completion announcements without unnecessary focus movement. Verify keyboard file selection and recovery from errors. The table gives expected outcomes, not executed production results. Working article materials and passing integration checks of the application server, validator and assistive technology are separate evidence.
After execution, add environment, version, owner, actual result and evidence.
| Sequence | Expected outcome | Evidence |
|---|---|---|
| Size boundaries: 1 / 10,000,000 bytes | Size passes; content checks still required | Server boundary decision |
| 0 / 10,000,001 bytes | Reject; no completion or submission | Size and error copy |
| Non-PDF with PDF extension | Reject according to server content checks | Validation result and UI |
| Choose password-protected PDF | Ask for an unprotected replacement | Rejection reason |
| 100%, delayed receipt response | Confirming; cannot submit | UI and absence of acceptance request |
| Checker outage after receipt | Pending confirmation, not a defective-file claim | Outage and guidance |
| Remove during check → late pass | No attachment remains | Selection version and accepted target |
| Same-name replacement → old pass | Only new file remains pending/complete | New attachment identifier |
| Completed → old checking response | Do not regress completion | Server status version |
| Unknown result → retry | Query original attempt; prevent duplication | Attempt processing records |
| Changed permission/duplicate submit | Server rejects or returns same application | Permission check and application identifier |
| Change during acceptance; keyboard; narrow screen | Explain block; accessible focus/status | UI and actual attachment association |
Keep the reason in the proposal and transitions in the spec
The proposal records why a PDF is necessary, the problem being solved and why server confirmation defines completion. The specification translates that into states, copy, actions and exceptions. Rather than listing screen numbers, connect each change to its outcome: removing during validation prevents any late response from restoring that attachment.
Engineering checks validation, permissions, deduplication, concurrency and temporary-file lifetime. QA compares UI sequences with actual attachments. Operations needs a traceable status path so unknown results are not announced as failures. After release, distinguish rejection reasons, exits during uncertainty and incorrect-file reports; do not put document content into analytics. Fewer events alone do not prove improvement: check whether missing attachments were actually resolved.
Fill in service constraints and owner confirmations, then link the spec and QA.
Required PDF attachment handoff — fictional workshop proposal Purpose: only the currently selected, server-validated file enters the submission. Selection, transfer, validation and application acceptance are separate. Input: one PDF, 1–10,000,000 bytes inclusive. The label is 10MB or smaller; 10MB means 10,000,000 bytes here. Empty, password-protected or rejected files cannot complete. Browser checks guide users; the server validates again. Selection: cancelling the picker preserves the current attachment. Selecting a new file excludes the previous one and advances the selection version. Invalid replacement never silently restores the old file. Preserve other form inputs. States: unselected → transferring → receipt confirmed → checking → current attachment usable. At 100%, unknown receipt means Confirming transfer. Known receipt with pending validation means Checking file. Neither permits submission. Completion: match current selection and attempt, server attachment ID, proposal association and validation pass. Compare server status versions so an old checking response cannot regress a completed state. Rejection: give actionable reasons for type, size, empty file, password or failed validation. A validation-service outage is not proof of a defective file; keep it unapproved and provide status checking/recovery. Removal/replacement: immediately invalidate local eligibility and old responses, and invalidate/exclude the old selection on the server. A late success cannot reattach it. UI removal, aborting transport and deletion of temporary server bytes are different outcomes. Same name: a replacement is a new selection and attempt. Associate the server attachment identifier, not just the filename. Unknown result: query the original attempt. Do not resend while it is processing. After a confirmed failure/non-receipt, resend only under an engineering-confirmed same-content/same-attempt deduplication and transition contract. Replacement uses a new attempt. Without that contract, provide status checking and explicit new selection instead of automatic resending. Submit: explain why an unready required attachment blocks submission. The server rechecks ownership, proposal association, selection version and validation consistently with acceptance. Prevent attachment changes during acceptance. If the result is unknown, query the same application identifier; do not create another application. After acceptance: preserve its attachment independently of the editing selection. This example provides no post-acceptance replacement. Decide temporary expiry, permanent retention and deletion separately with the actual service owner. Accessibility: retain a native file input and keyboard access. Announce textual progress/status without unnecessary focus movement. Keep error instructions and the file input reachable. Documents and owners: the proposal explains need, completion criteria and alternatives. The spec maps states, copy, versions, requests/responses and exceptions. Engineering verifies validation, permission, concurrency, deduplication and temporary-file lifetime; QA compares UI sequences with actual attachment IDs; operations needs traceable status and response guidance. Acceptance evidence: execute boundaries, 100%, rejection, checker outage, same-name replacement, late success after removal, old status responses, unknown results, changed permission and changes/duplicates during acceptance. Record environment, version, owner, expected/actual result and evidence. This handoff is not a passed integration test of a real server.
Download the engineering and QA handoff
Sources and example conditions
An independent fictional workshop-proposal case informed by GOV.UK, OWASP and W3C documents checked on 30 September 2026. One PDF, 10MB and the completion/replacement policies are example design choices. Written by WekeyLab AI without private company material or invented personal experience or outcomes. AI prompts are unexecuted examples. English and Chinese localize the same Korean case. Article interaction verification is separate from real application integration acceptance.
GOV.UK Design System — File upload