fetch-codex-manual.mjs fails after codex-manual.md redirect drops x-content-sha256
What happened
The bundled openai-docs skill helper fails while fetching the Codex manual:
$ node ~/.codex/skills/.system/openai-docs/scripts/fetch-codex-manual.mjs
Error: Manual response is missing x-content-sha256.
The published manual URL now redirects to learn.chatgpt.com. The initial 308 response includes x-content-sha256, but the final 200 response does not. Because the helper follows the redirect and calls readHeaderSha() on the final response, it rejects the response before fetching or validating the manual body.
The relevant implementation is:
Steps to reproduce
- Run the bundled helper:
``sh``
node ~/.codex/skills/.system/openai-docs/scripts/fetch-codex-manual.mjs
- Inspect the original response:
``sh``
curl -sS -I https://developers.openai.com/codex/codex-manual.md
Relevant headers:
``text``
HTTP/2 308
location: https://learn.chatgpt.com/docs/codex-manual.md
x-content-sha256: f871659e2e29a28eea4ba1b010a7038461cbaf3e2b931c6e2cf8301bb1a857cd
- Follow the redirect:
``sh``
curl -sS -I -L https://developers.openai.com/codex/codex-manual.md
The final response is HTTP/2 200 from learn.chatgpt.com, but it has no x-content-sha256 header.
Expected behavior
fetch-codex-manual.mjs should successfully fetch and verify the current Codex manual after the redirect. Possible fixes include preserving the hash from the redirect response, adding the hash header to the final response, or using another integrity check for the downloaded body.
Actual behavior
The helper aborts with Manual response is missing x-content-sha256.
Environment
- Codex CLI:
0.143.0 - macOS:
26.5.1(25F80) - curl:
8.7.1 - Observed: 2026-07-10
Related issues
- #22623 covers Node helper proxy handling, which can cause an earlier but separate fetch failure.
- #31653 covers availability/version churn of the same manual-fetch helper, but not this redirect/header regression.
7 Comments
+1
I reproduced this on Codex CLI
0.144.1, macOS26.5, with the currentmainhelper matching the installed system skill.One important detail for choosing the fix: preserving
x-content-sha256from the initial308response is not valid for the final manual body. In my live reproduction, the redirect supplied:while the SHA-256 computed from the final redirected manual body was:
I validated a client-side fallback with the following behavior:
Regression checks covered:
updated; second run reportedalready current.A server-side fix that restores the correct hash on the final
learn.chatgpt.comresponse would also preserve the original helper design. Until then, computing the final HTTPS body digest provides a small client-side compatibility fallback without weakening mismatch checks for responses that do provide the header.Additional reproduction from macOS:
0.143.0.f53eb6d2f286e9efcc397e8bee93a938e37296c90953e4e06e94899ef1b6c363, byte-identical to both therust-v0.144.1release and currentmain.x-content-sha256on the initial308, while the final200fromlearn.chatgpt.comstill lacks the header. This rules out proxy header stripping as the cause in this reproduction.148b387f4b70f506f21d582ba27d499ba1fbf10908ae89a67cbadf4df64317db, while repeated downloads of the final body produced stable SHA-2563b1b65de3fdd027d4a034276531f1ea2cc9ded2db4bf4569469977c8875c6065.This further supports an endpoint/helper contract regression rather than a local configuration problem. We are not applying a local patch because the docs fallback path keeps normal usage unblocked.
I'm also getting integrity check failures every time codex tries to load data for its official manual from online. This is for codex 0.144.1 on macOS. Seems like it'd be good if there was integration tests that that automatically compared the checksums in codex vs what is requested from online.
Confirming this also affects my Codex Desktop environment:
0.144.0-alpha.415.7.3(24G419)8.7.1f53eb6d2f286e9efcc397e8bee93a938e37296c90953e4e06e94899ef1b6c363Sandboxed networking is enabled and both
developers.openai.comandlearn.chatgpt.comare explicitly allowlisted and reachable. After restarting Codex, the helper still fails consistently withManual response is missing x-content-sha256.The initial
308contains the header, while the final redirected200does not. The official Docs MCP fallback works, but this causes repeated visible failure/fallback noise across tasks. This appears to be the same endpoint/helper contract regression rather than a local networking or allowlist problem.Additional Windows/CLI reproduction and tested client-side compatibility patch
I reproduced this on Codex CLI 0.144.3 / Windows / PowerShell with the installed helper byte-equivalent to the current official source blob
b2605520dc54aa3b71769e90887b9fdf06c97da4before modification.The observed response chain was:
The proxy preserved the initial
308checksum header, so proxy header stripping was not the root cause in this reproduction. The final200simply did not include the header.It is also unsafe to reuse the checksum from the
308for the final body. In this run:I applied and tested the following compatibility semantics locally:
hitwithout rewriting an unchanged cache.verificationModeasheader-sha256orlocal-sha256so the fallback is explicit and not represented as a server-provided checksum.Core diff against the current helper:
Regression tests covered:
Live endpoint verification after applying the patch:
A second live run produced the same digest with:
Security boundary:
local-sha256provides download/cache consistency over the final HTTPS body, but it is not an independently server-authenticated digest. A server-side fix that restores a correctx-content-sha256or standardContent-Digeston the final200remains preferable. The fallback is explicit, preserves all mismatch checks when a header is provided, and does not trust the mismatching redirect checksum.I subsequently restored my local installed helper to the exact official 0.144.3/main bytes while waiting for an upstream decision; the results above are from the tested first-round compatibility patch, not a claim that this behavior is currently shipped by OpenAI.
Rather than fixing only the current redirect, I suggest treating this as a resilience contract for the bundled docs skill.
Proposed behavior
HEADrequest. A CDN may omit or change headers betweenHEAD, redirects, and the finalGET. UseGETas the source of truth; useETag/Last-Modifiedfor conditional requests when available.Content-Digestor the existingx-content-sha256; a malformed digest or body mismatch remains a hard validation failure.verificationMode: "local-sha256"(not as equivalent to a server-authenticated digest).Suggested acceptance tests
HEADunsupported or inconsistent withGET;304 Not ModifiedviaETag/Last-Modified;This keeps strict verification whenever the server provides integrity metadata while avoiding a single non-standard header becoming a hard availability dependency for built-in Codex documentation.