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

  1. Guard the call: if (request.method !== 'GET') skip cache.put.
  2. Store POST responses yourself (KV/SQLite) keyed by URL plus body hash.
  3. 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

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


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/78dc6d3892c6c0c7. Report an issue: GitHub.