Skip to content

fix(cli): name the refused file and parameter when a cloud upload is rejected - #7155

Merged
miguel-heygen merged 2 commits into
mainfrom
dcloudpro/cloud-upload-error-message
Nov 4, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
dcloudpro/cloud-upload-error-message

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

What changed

When the cloud refuses an uploaded file at the last step of the upload, the CLI now says which file and what the server said. A type refusal reads The cloud couldn't read this audio file's type: song.mp3. It said: Stored file type not supported: application/octet-stream; any other refusal (expired, size, checksum) reads The cloud refused song.mp3: <server message>. The error box also prints the server's param next to its message, when it sends one. Before, the box showed only the server's bare invalid-parameter text, so a person or a bug report could not tell which file or field was refused.

Why

Pro cloud exports fail at POST /v3/assets/{id}/complete with INVALID_PARAMETER (mp3, webm and mp4 files). The server reads the first 8 KB of the stored file and refuses what it cannot classify; the fix for the rule itself is server-side. This change only makes the failure readable on the CLI side.

fails without the fix: upload.test.ts "names the file and keeps the server's words when complete refuses its type" and errors.test.ts "names the refused parameter next to the server's message" both fail on main (2 failed, 23 passed) and pass with it; a third test pins that an expired upload does not blame the type (26 pass), run on miga.

What I did NOT exercise

Not run against the real API or a real refused upload: the tests use a stubbed client. The CLI's own file-type check (bytesMatchExtension) is unchanged on purpose.

Size

About 25 lines of code and 45 of tests in 4 files; nothing open to fold it into.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes at 62a83790. The fails without the fix: line is present, both named tests fail on main as described, and the errors.ts "(parameter: …)" change is fine. The blocker is the wording nameRefusedFile adds.

Blocker: every invalid_parameter from complete is labelled a file-type problem.
nameRefusedFile rewrites any invalid_parameter from completeAssetUpload to "The cloud couldn't read this {noun}'s type: {filename}. It said: …". On the server (movio/api_service/app/service/asset_upload.py → finalize_external_asset_upload), complete returns INVALID_PARAMETER for several failures that have nothing to do with the file's type:

  • _raise_if_expired: "This upload has expired; create a new upload."
  • _raise_if_checksum_differs: "Provided checksum_sha256 does not match the checksum declared at upload creation."
  • _verify_staged_upload: "Uploaded object size does not match the declared size."

With this PR, an expired upload prints "The cloud couldn't read this audio file's type: song.mp3. It said: This upload has expired; create a new upload." That sends the person, or whoever reads the bug report, looking at the file type. Since the PR's goal is a readable error, this works against it.

Two ways to fix it, either is fine:

  • Use a neutral prefix for every invalid_parameter, such as "The cloud refused song.mp3: {server message}". You still get the file name and keep the server's words.
  • Or keep "couldn't read this file's type" only for the type refusals (Stored file type …, content_type not allowed: …, Stored file does not have a ZIP signature.), and use the neutral prefix for everything else.

Then add one test where complete returns a non-type invalid_parameter, for example the expired message, and assert it does not claim a type problem.

Minor, not blocking: building a new HyperframesApiError drops the original stack. If you want to keep it, pass cause: err, which needs a small constructor change, or set the stack on the new error.

CI when I reviewed: Comments, regression, PR captures and Player perf had passed. CI, CodeQL, Windows render verification and preview-regression were still running.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at e6b9dadd. The blocker from my review at 62a83790 is fixed.

  • Only type refusals mention the type now. "couldn't read this file's type" appears only when the server message starts with Stored file type, content_type not allowed or Stored file does not have a ZIP. That covers every type refusal _resolve_real_file_type raises on the server, including the declared-vs-stored mismatch. Every other complete-time invalid_parameter gets the neutral "The cloud refused {file}: {server message}": expired, checksum mismatch and size mismatch.
  • New test: "does not blame the file's type when complete refuses an expired upload" pins the neutral wording.
  • fails without the fix: is still present, and it names the two tests that fail on main.
  • CI: Test (cli 1/2), Test (cli 2/2), Typecheck, Lint, Comments, regression, PR captures and Player perf passed. CodeQL, Windows render verification, preview-regression and the rest of CI were still running when I approved.

Not blocking: the original stack is still dropped when the error is rebuilt.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit 11f4326 Nov 4, 2026
70 checks passed
@miguel-heygen
miguel-heygen deleted the dcloudpro/cloud-upload-error-message branch November 4, 2026 11:39
SanHsien added a commit to SanHsien/hyperframes that referenced this pull request Nov 4, 2026
…heygen-com#7155; review through 1ff4cef

- heygen-com#7143: inline nested sub-composition timelines (pageBuild goldens
  follow upstream).
- heygen-com#7151: makeOutputFolder skips mkdirSync for existing folders, so
  drive-root outputs like C:\ no longer fail with EPERM.
- heygen-com#7154: a page that never becomes ready reports PAGE_NEVER_READY
  instead of a generic evaluate timeout (adapted by hand).
- heygen-com#7155: cloud upload error handling.
Watermarks: commit 1ff4cef, PR 7157; monitored 88. Ledger in
docs/UPSTREAM_REVIEW_2026-11-04_CONTINUED.md.

Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant