denoland/deno · error · TypeError
Request method must be GET
Error message
Request method must be GET
What it means
Step 4 of Cache.put(): only GET requests may be stored, because cache matching is defined only for GET. `innerRequest.method !== 'GET'` throws this TypeError.
Source
Thrown at ext/cache/01_cache.js:154
response = webidl.converters["Response"](response, prefix, "Argument 2");
// Step 1.
let innerRequest = null;
// Step 2.
if (ObjectPrototypeIsPrototypeOf(RequestPrototype, request)) {
innerRequest = toInnerRequest(request);
} else {
// Step 3.
innerRequest = toInnerRequest(new Request(request));
}
// Step 4.
const reqUrl = new URL(innerRequest.url());
if (reqUrl.protocol !== "http:" && reqUrl.protocol !== "https:") {
throw new TypeError(
`Request url protocol must be 'http:' or 'https:': received '${reqUrl.protocol}'`,
);
}
if (innerRequest.method !== "GET") {
throw new TypeError("Request method must be GET");
}
// Step 5.
const innerResponse = toInnerResponse(response);
// Step 6.
if (innerResponse.status === 206) {
throw new TypeError("Response status must not be 206");
}
// Step 7.
const varyHeader = getHeader(innerResponse.headerList, "vary");
if (varyHeader) {
const fieldValues = StringPrototypeSplit(varyHeader, ",");
for (let i = 0; i < fieldValues.length; ++i) {
const field = fieldValues[i];
if (StringPrototypeTrim(field) === "*") {
throw new TypeError("Vary header must not contain '*'");
}
}
}View on GitHub (pinned to 89f33cbef2)
Solutions
- Guard the call: if (request.method !== 'GET') skip cache.put.
- Store POST responses yourself (KV/SQLite) keyed by URL plus body hash.
- When only the payload matters, construct a GET Request for the same URL and cache that.
Example fix
// before
await cache.put(req, res); // req.method === 'POST'
// after
if (req.method === 'GET') {
await cache.put(req, res);
} else {
await kv.set(['post', req.url], await res.clone().text());
} Defensive patterns
Strategy: validation
Validate before calling
const req = input instanceof Request ? input : new Request(input);
if (req.method === 'GET') {
await cache.put(req, response);
} Try / catch
try { await cache.put(req, res); } catch (e) { if (e instanceof TypeError && /GET/.test(e.message)) { /* store elsewhere */ } else throw e; } Prevention
- Check request.method before every cache.put in shared/interceptor code.
- Remember the whole Cache API (put and match) is GET-only by spec.
When it happens
Trigger: cache.put(new Request(url, { method: 'POST' }), response) — any non-GET method, including POST, PUT, and HEAD.
Common situations: Saving POST/PUT responses for offline replay; fetch-interception code that forwards the original request method into a cache.put call.
Related errors
- Request url protocol must be 'http:' or 'https:': received '
- Vary header must not contain '*'
- BenchContext::end() has already been invoked
- Object is not a valid image or a path to an image. `Deno.jup
- Response status must not be 206
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/78dc6d3892c6c0c7.
Report an issue: GitHub.