Skip to content

id(web): mimeToExtension returns Object.prototype members for prototype-named MIME types — 'constructor' yields the Object constructor instead of 'bin', corrupting paste filenames #2920

Closed

Description

@dezren39

id(web): mimeToExtension returns Object.prototype members for prototype-named MIME types — 'constructor' yields the Object constructor instead of 'bin', corrupting paste filenames

Evidence (verified this run, main 321dc21)

pkgs/id/web/src/image-upload.ts:43-54 — the extension table is a plain object literal and the fallback relies on nullish coalescing:

export function mimeToExtension(mime: string): string {
  const map: Record<string, string> = { "image/png": "png", /* … */ };
  return map[mime] ?? "bin";
}

?? "bin" only fires for null/undefined. For a key that exists on Object.prototype, the lookup returns the inherited member — never nullish — so the fallback never runs and the function returns a function or object despite its declared string return type.

Probe (the function's verbatim lines 43-54 extracted from this HEAD; laptop ~/git/fleet/probe-2026-10-30-laneA-mimext/, bun run probe.ts):

mime result (runtime type)
image/png "png" (string, correct)
application/octet-stream "bin" (correct)
"" "bin" (correct)
constructor function Object() { [native code] } (function)
toString function toString() { [native code] } (function)
hasOwnProperty function hasOwnProperty() { [native code] } (function)
__proto__ [object Object] (object)

Downstream, generatePasteFilename (image-upload.ts:76-79) interpolates the result into a filename, so mimeToExtension("constructor") yields paste-<ts>.function Object() { [native code] } — a filename containing spaces, braces and parentheses — instead of paste-<ts>.bin. That name is used for pasted images whose File.type is empty/unrecognized (handleImageUpload, :237), a value ultimately supplied by the clipboard/drag source.

Why it matters

Same plain-object-lookup class fixed for detectLanguage in #2787 and for LANG_IMPORTS in highlight.ts:284-286 (own-key check, with an explanatory comment) — image-upload.ts was missed, and its ?? fallback makes the failure silent: no error, just a non-string "extension" flowing into a generated filename and upload metadata. The existing tests (image-upload.test.ts:109-143) pin the seven real types plus two unknown-string cases, but no prototype-name case.

Acceptance criteria

Dedup: searched open + closed issues for mimeToExtension / image-upload prototype this run — no hits. #2787 covers highlight.ts only. Sibling filed the same run: #2919 (terminalBytesForKey in world-keyboard.ts, same class, different file/function/caller — independently fixable).

Activity

  1. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/lowNice to have; do when convenient
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 31, 2026
  2. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  3. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    Cross-link from the filing run: #2792 is the open design issue for one own-key rule across dynamic lookups; this filing is a concrete verified instance in image-upload.ts (mimeToExtension) for its tracker. Sibling instance: #2919.

  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  5. 5 remaining items

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 1, 2026
  7. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  8. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  9. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  10. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

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

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientsource/creatorFiled by the new-issue-creator jobtask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions