close the media 403 investigation: the bytes are gone

The render check settled it. Scrolling the whole conversation found sets of
images that do NOT display in ChatGPT — a set of 6 and a set of 4 — and they
are exactly our failures: the 6 are the records that 404 outright, the 4 are
the refused attachment batch we dumped (image.png, image(1).png,
image(2).png + 1). Every set that displays downloaded fine.

So the 403 was never OpenAI withholding something. It is the same failure
their own UI hits. All 19 are unrecoverable.

What the investigation established, now recorded in media.py and the
changelog so it is not repeated:
  - uploads do not expire (36/36 sampled, 2025-09 → 2026-08, still live), so
    export cadence was never the variable
  - 7 records 404; 12 report state=ready with a library_file_id
  - /files/{id}/download mints the signed estuary/content URL the UI fetches,
    and refuses the survivors regardless of headers, Authorization, gizmo_id,
    conversation_id, Referer or namespace; the Library id is file_not_found
  - all survivors were created 2026-07-14 within minutes of each other yet
    appear in conversations predating that date — a Library migration that
    kept the metadata and lost the bytes

Dropping the nine one-off probes; their findings live in the code comments
and changelog, and git history has the scripts if they are ever wanted.
This commit is contained in:
JesseMarkowitz
2026-08-17 12:47:05 -04:00
parent d30a9510bb
commit dfa0645fba
11 changed files with 17 additions and 1627 deletions
+13 -2
View File
@@ -160,8 +160,19 @@ def _classify_failure(error: ProviderError) -> str:
Note that a bare 403 from ChatGPT usually means *gone*, not *refused*:
its download endpoint reports a deleted upload as 403 Forbidden. The
provider confirms that against /files/{id} before raising, so a failure
that reaches here still saying "forbidden" is one where the asset really
does still exist — worth looking at, unlike an expired upload.
that reaches here still saying "forbidden" is one where the file record
survives.
``forbidden`` does NOT mean recoverable. Investigated exhaustively
2026-08-17 (19 assets): those records report ``state: "ready"`` and carry
a ``library_file_id``, yet /files/{id}/download — the endpoint that mints
the signed estuary/content URL the web UI itself fetches — refuses them,
and the Library id is rejected as ``file_not_found``. Decisively, the same
images render blank in ChatGPT's own UI. Nothing was withheld from us; the
bytes are gone and only the metadata survived, apparently from a Library
migration dated 2026-07-14. Do not spend another afternoon on it: no
header, scope, namespace or id form reaches these. The bucket stays
separate only because the two failures look different on the wire.
"""
detail = str(error.original).lower()
if "404" in detail or "not found" in detail or "no longer exists" in detail: