Skip to content

Accept MKV, and say why a file was refused - #11

Merged
DomDom3333 merged 4 commits into
mainfrom
claude/mkv-upload-support-ka4jq4
Aug 18, 2026
Merged

DomDom3333 merged 4 commits into
mainfrom
claude/mkv-upload-support-ka4jq4

Conversation

@DomDom3333

@DomDom3333 DomDom3333 commented Aug 18, 2026 •

Copy link
Copy Markdown
Owner

An .mkv upload had two ways to end badly. Small ones were refused for an
extension nothing claimed, with "Unsupported file type" and no hint at what
would have worked. Large ones never got that far: the whole body is sent
before anything looks at it, so a clip over the request-body limit had its
connection cut mid-send and reached the uploader as a bare "network error" —
the same message a dropped connection gives, with nothing to suggest the size
was the problem. Converting the clip to a smaller MP4 made both go away, which
points at neither.

Matroska needed nothing but the extension: it shares WebM's container, so the
header check already recognised it and ffmpeg already takes frames from it.

The refusals now happen in the browser, before a byte is sent. The handlers
own the extension list and their own ceilings, so the page can hand the
browser what the server takes and both stay in step; a file that doesn't fit
is turned away as it's picked, named and measured against the limit it broke.
The upload card says up front what does fit, the server repeats the same
wording for anything that reaches it, and the XHR error case no longer
pretends a severed upload was only ever the network.

claude added 4 commits August 17, 2026 19:54
An .mkv upload had two ways to end badly. Small ones were refused for an
extension nothing claimed, with "Unsupported file type" and no hint at what
would have worked. Large ones never got that far: the whole body is sent
before anything looks at it, so a clip over the request-body limit had its
connection cut mid-send and reached the uploader as a bare "network error" —
the same message a dropped connection gives, with nothing to suggest the size
was the problem. Converting the clip to a smaller MP4 made both go away, which
points at neither.

Matroska needed nothing but the extension: it shares WebM's container, so the
header check already recognised it and ffmpeg already takes frames from it.

The refusals now happen in the browser, before a byte is sent. The handlers
own the extension list and their own ceilings, so the page can hand the
browser what the server takes and both stay in step; a file that doesn't fit
is turned away as it's picked, named and measured against the limit it broke.
The upload card says up front what does fit, the server repeats the same
wording for anything that reaches it, and the XHR error case no longer
pretends a severed upload was only ever the network.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYoVr4rkVdeQn5THttcGRM
Correcting the previous commit's account of the cause: the size limit is not
what refused a 150 MB clip, and an unsupported extension does not produce a
network error by itself. Uploading a 150 MB .mkv to the old code returns a
clean JSON rejection, 200 and all.

What does produce it is any failure the browser can't attribute to a response.
Reproduced two: a body past the request-body limit dies after ~4 MB of a 250 MB
send with a 500 and a severed connection, and a box that is gone or locked
answers before the body is read at all, cutting off an upload already in
flight. All three of those — plus a proxy hanging up on a body it thinks too
big, and a genuinely dropped connection — reach the page as one bare error
event carrying nothing to act on, and the page was turning every one of them
into the same three words.

So it stops guessing and asks. A failed upload is followed by a request small
enough to answer when a large one just died, and what comes back separates
box gone from box locked from box fine — the last meaning it was that upload
in particular the server would not take. The same probe now covers a response
that isn't ours, which an error page from a proxy would be.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYoVr4rkVdeQn5THttcGRM
The page was filling in its own explanation whenever the response didn't hand
it one, and the explanation it reached for was the connection. That is how an
unsupported format arrives as "network error": nothing on the wire was wrong,
the client just had no reason to show and picked the wrong one.

So the reason comes from the server now, on every path that can fail. A box
that expired, a box that locked itself again, a malformed request and a body
past the request limit all answer in the same shape as a success, with the
reason in the body. The last of those never answered at all before — Kestrel
throws on an over-limit body and the exception handler returns an HTML error
page, so a 500 with no mention of size was all a 250 MB upload ever got back.
Catching it turns that into a 413 that names the ceiling it broke.

The page shows what it was told and nothing else. A status code with no body
is reported as that status code, a reply that isn't ours is reported as one,
and a request that got no reply says only that. No cause is asserted that
wasn't given, which also removes the follow-up request added a commit ago:
asking a second question is not how the first one should have been answered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYoVr4rkVdeQn5THttcGRM
Drops the format hint under the upload card and its styling, the progress-row
styling, the generated accept attribute (the existing one just gains .mkv),
and the commentary that had grown longer than the code it sat above.

Tests keep the two that would fail if this regressed: an .mkv upload being
stored and served as a video, and an over-limit body answering 413 with the
reason rather than 500 and an HTML page. The rest asserted message wording
and page markup, which the code they cover already reads plainly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYoVr4rkVdeQn5THttcGRM
@DomDom3333 DomDom3333 changed the title Accept MKV, and say why a file was refused instead of failing silently Accept MKV, and say why a file was refused Aug 18, 2026
@DomDom3333
DomDom3333 merged commit 4d5d52e into main Aug 18, 2026
1 check passed
@DomDom3333
DomDom3333 deleted the claude/mkv-upload-support-ka4jq4 branch August 18, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants