Skip to content

bug: transcript downloads get a .json filename when the stored media type differs in case #4982

Description

@breken-ai

Provide environment information

Not environment-specific: found in the webapp source at main @ c2b7a72 and reproduced with the webapp's own Vitest suite (macOS arm64, pnpm).

Describe the bug

downloadTranscript (apps/webapp/app/services/realtime/transcriptDownload.server.ts:11-15) picks the .jsonl filename only when the stored media type exactly equals TRANSCRIPT_BLOB_CONTENT_TYPE (application/vnd.trigger.transcript+ndjson):

contentType.split(";")[0]?.trim() === TRANSCRIPT_BLOB_CONTENT_TYPE

Media types are case-insensitive (RFC 9110 §8.3.1). An object whose Content-Type comes back in a different case, for example from an S3-compatible store or proxy that normalizes header values, is the same indexed transcript, but it downloads as snapshot.json rather than snapshot.jsonl. Line-oriented tools then get the wrong extension.

Expected: the comparison is case-insensitive, and the filename is .jsonl for any casing of the transcript media type.

Reproduction repo

N/A (unit test against this repo, below)

To reproduce

Add this to apps/webapp/app/services/realtime/transcriptDownload.server.test.ts:

test("uses a .jsonl filename for transcript media types regardless of case", () => {
  const object = new Response('{"version":2}\n', {
    headers: { "Content-Type": TRANSCRIPT_BLOB_CONTENT_TYPE.toUpperCase() },
  });
  const response = downloadTranscript(object, "packets/download/snapshot.json");
  expect(response.headers.get("Content-Disposition")).toBe('attachment; filename="snapshot.jsonl"');
});

On main it fails with filename="snapshot.json".

Additional information

A 1-line fix (lowercase before comparing) with this regression test and a .server-changes note is ready on the breken-ai/trigger.dev fork (breken/fix-transcript-mime-case). The related Vitest suite, oxfmt, oxlint and webapp typecheck pass. I'll open it as a draft PR with fixes #<this> once the account is vouched.

Prepared with AI assistance (Claude) from the breken-ai account.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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