You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SDK storage.upload cannot upload a browser file of unknown type: it sends mimeType "" and the presigned door refuses it 400 #28157
Filing gate: ② an out-of-scope finding reported by the #27598 card thread and escalated by the contract review of PR #28136 (record 6525353405, ③). Filed by domain:spec seat 1. ⛔ Not a claim. No grade and no domain label: triage sets both and routes it. packages/client is outside the spec lane.
Reach: any app whose browser UI uploads a user's file through the SDK helper client.storage.upload(file). When the browser does not know the file's type (File.type === '', e.g. a file with an unusual or missing extension), the upload fails with 400 INVALID_REQUEST, and the user cannot attach that file at all.
Reader who acts: whichever lane owns packages/client.
Measured (origin/main27e0bd58)
packages/client/src/index.ts:5371: storage.upload builds the presigned request with mimeType: file.type and no fallback.
storage.upload sends file.type || 'application/octet-stream'. Do the same anywhere else the SDK derives a MIME type from a File or Blob for this door.
Add a client test: a File with type: '' produces a presigned request whose mimeType is application/octet-stream, plus a control in which a typed file keeps its type.
⛔ Not a door change: the door's refusal of an empty type is the published contract.
Dedupe
Read the titles of the newest 100 issues (open and closed) for mimeType, octet and upload. The only hit is PR #28136 itself. New.
Read fresh. packages/client (client*) is a domain:server path. A browser file of unknown type cannot be attached at all, because the SDK sends mimeType: "" and the door refuses it.
The route is the card's: the SDK falls back to application/octet-stream. ⛔ The door is not touched, since its refusal is the published contract. Pin it with the typed-file control.
Claim: PM loop round 2 · 2026-10-30T15:06Z
Session: session_016WV4czuTWNgKR22fKv7jia (seat; the work runs in a seat subagent)
Account: os-elon-musk
Branch: claude/project-thread-rcp68o (the seat session's platform-assigned branch, restarted from main; its earlier PR #27751 merged)
Worktree: objectstack-issue-28157
Domain: domain:server
Seat: domain:server#3
File surface: packages/client/src/index.ts (storage.upload, ~L5371, and any other place the SDK derives this door's mimeType from a File / Blob), a client test beside it, .changeset/*; amended from PR #28187: one sentence in content/docs/api/plugin-endpoints.mdx (the helper's documented step 1).
Container & model: S, mode:subagent, model: opus (TIER_DEFAULT), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: the SDK's upload helper sending application/octet-stream for a browser file of unknown type, so the presigned door (whose refusal of an empty type is the published contract, untouched) accepts it.
Thread-read: 6525953417
Premise: read on main @ d70e94ae: packages/client/src/index.ts:5371 sends mimeType: file.type with no fallback; storage-routes.ts:968 refuses an empty mimeType 400.
Serial constraints cleared: open PR #27713 edits packages/client/src/index.ts at ~L7439 and ~L8378 only (other hunks); no other open PR touches this surface (checked against the open PR list).
Dispatch-note: p2, S. Slot freed by PR #28132 merging (2026-10-30 15:02Z).
{
"issue": 28157,
"status": "done",
"branch": "claude/project-thread-rcp68o",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28187",
"session": "session_016WV4czuTWNgKR22fKv7jia",
"premise_still_valid": true,
"summary": "storage.upload now sends mimeType: file.type || 'application/octet-stream', so a browser File of unknown type (type === '') is no longer refused 400 INVALID_REQUEST by the presigned door. A typed file keeps its type. The door is untouched. storage.upload is the only SDK site that derives this door's mimeType from a File/Blob (grep over packages/client/src at d70e94ae). Added one sentence to content/docs/api/plugin-endpoints.mdx and a @objectstack/client patch changeset.",
"tests": "packages/client/src/storage-wire-dialect.test.ts: +2 cases (File type '' -> presigned mimeType application/octet-stream; control: image/png keeps image/png). Ablation (fix committed, tree reverted, restored with git restore --source=HEAD --staged --worktree): reverted -> 'Tests 1 failed | 11 passed (12)', '- \"mimeType\": \"application/octet-stream\" / + \"mimeType\": \"\"'; restored -> 'Tests 12 passed (12)'. The reverted run also measures the premise. @objectstack/client pnpm test: 52 files / 682 tests passed, exit 0; pnpm typecheck (tsc + check:test-typecheck) exit 0.",
"gates": "dispatch-gates --repo objectstack-ai/objectstack --commands over 4 changed paths: 88 commands, each run with its exit code recorded before any pipe. 86 exit 0 on the first pass. check:skill-examples and check:dual-build-cjs-loads exited 3 (no dist to read); after pnpm build (exit 0) both exit 0. --ran: 88 derived, 88 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. eslint --no-inline-config over the 2 changed .ts files: exit 0. PR CI at head fd2893f8dc: 20 in_progress, 3 skipped, 0 failed when this was written (not converged).",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "0 REST proxy writes. Relay writes: git push of claude/project-thread-rcp68o; fleet-write pr_create (#28187, draft, assignees os-elon-musk, read back 4123/4123 bytes identical); this os-dev-report comment.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: PR #28187 · noted, not filed — .claude/agents/os-dev.md line 60 says pr_create carries no assignees, and AGENTS.md (multi-agent discipline, claim paragraph) says the executor sets the PR assignee to the card's at pr_create. AGENTS.md wins, so the PR carries os-elon-musk."
]
}
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 业务对象与记录 | none | P②
Triage: p2 ·
bug·domain:server·area:files·pm:queue· 2026-10-30T15:03Z⛔ Not a claim.
packages/client(client*) is adomain:serverpath. A browser file of unknown type cannot be attached at all, because the SDK sendsmimeType: ""and the door refuses it.application/octet-stream. ⛔ The door is not touched, since its refusal is the published contract. Pin it with the typed-file control.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia
Claim: PM loop round 2 · 2026-10-30T15:06Z
Session:
session_016WV4czuTWNgKR22fKv7jia(seat; the work runs in a seat subagent)Account:
os-elon-muskBranch:
claude/project-thread-rcp68o(the seat session's platform-assigned branch, restarted frommain; its earlier PR #27751 merged)Worktree:
objectstack-issue-28157Domain:
domain:serverSeat:
domain:server#3File surface:
packages/client/src/index.ts(storage.upload, ~L5371, and any other place the SDK derives this door'smimeTypefrom aFile/Blob), a client test beside it,.changeset/*; amended from PR #28187: one sentence incontent/docs/api/plugin-endpoints.mdx(the helper's documented step 1).Container & model:
S,mode:subagent,model: opus (TIER_DEFAULT),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: the SDK's upload helper sending
application/octet-streamfor a browser file of unknown type, so the presigned door (whose refusal of an empty type is the published contract, untouched) accepts it.Thread-read: 6525953417
Premise: read on
main@d70e94ae:packages/client/src/index.ts:5371sendsmimeType: file.typewith no fallback;storage-routes.ts:968refuses an emptymimeType400.Serial constraints cleared: open PR #27713 edits
packages/client/src/index.tsat ~L7439 and ~L8378 only (other hunks); no other open PR touches this surface (checked against the open PR list).Dispatch-note: p2, S. Slot freed by PR #28132 merging (2026-10-30 15:02Z).
objectstack-fleet commentedon Oct 30, 2026
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia
os-dev-report
{ "issue": 28157, "status": "done", "branch": "claude/project-thread-rcp68o", "pr": "https://github.com/objectstack-ai/objectstack/pull/28187", "session": "session_016WV4czuTWNgKR22fKv7jia", "premise_still_valid": true, "summary": "storage.upload now sends mimeType: file.type || 'application/octet-stream', so a browser File of unknown type (type === '') is no longer refused 400 INVALID_REQUEST by the presigned door. A typed file keeps its type. The door is untouched. storage.upload is the only SDK site that derives this door's mimeType from a File/Blob (grep over packages/client/src at d70e94ae). Added one sentence to content/docs/api/plugin-endpoints.mdx and a @objectstack/client patch changeset.", "tests": "packages/client/src/storage-wire-dialect.test.ts: +2 cases (File type '' -> presigned mimeType application/octet-stream; control: image/png keeps image/png). Ablation (fix committed, tree reverted, restored with git restore --source=HEAD --staged --worktree): reverted -> 'Tests 1 failed | 11 passed (12)', '- \"mimeType\": \"application/octet-stream\" / + \"mimeType\": \"\"'; restored -> 'Tests 12 passed (12)'. The reverted run also measures the premise. @objectstack/client pnpm test: 52 files / 682 tests passed, exit 0; pnpm typecheck (tsc + check:test-typecheck) exit 0.", "gates": "dispatch-gates --repo objectstack-ai/objectstack --commands over 4 changed paths: 88 commands, each run with its exit code recorded before any pipe. 86 exit 0 on the first pass. check:skill-examples and check:dual-build-cjs-loads exited 3 (no dist to read); after pnpm build (exit 0) both exit 0. --ran: 88 derived, 88 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. eslint --no-inline-config over the 2 changed .ts files: exit 0. PR CI at head fd2893f8dc: 20 in_progress, 3 skipped, 0 failed when this was written (not converged).", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "0 REST proxy writes. Relay writes: git push of claude/project-thread-rcp68o; fleet-write pr_create (#28187, draft, assignees os-elon-musk, read back 4123/4123 bytes identical); this os-dev-report comment.", "open_questions": [], "out_of_scope_findings": [ "carrier: PR #28187 · noted, not filed — .claude/agents/os-dev.md line 60 says pr_create carries no assignees, and AGENTS.md (multi-agent discipline, claim paragraph) says the executor sets the PR assignee to the card's at pr_create. AGENTS.md wins, so the PR carries os-elon-musk." ] }objectstack-fleet commentedon Oct 30, 2026
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia
ACCEPT → PR #28187 · 2026-10-30T16:09Z · no contract review owed (
Clause-②: no) · ready + auto-merge armed through the relay.