denoland/deno · error · TypeError

Method is not valid

Error message

Method is not valid

What it means

Request's constructor normalizes the method via validateAndNormalizeMethod, which first tests the string against the HTTP token code-point regex (visible ASCII token characters only: A-Z a-z 0-9 and !#$%&'*+-.^_`|~). A method containing spaces, slashes, parentheses, non-ASCII characters, or an empty string fails the regex and throws TypeError "Method is not valid".

Solutions

  1. Use a plain token method string: GET, POST, or a custom token like PROPFIND
  2. Trim whitespace and reject empty strings before constructing the Request
  3. Validate the method against /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ in your config loader

Example fix

// before
const method = config.method ?? "";
new Request("https://example.com", { method }); // throws when empty or "GET /x"

// after
const TOKEN_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
const method = config.method && TOKEN_RE.test(config.method) ? config.method : "GET";
new Request("https://example.com", { method });
Defensive patterns

Strategy: validation

Validate before calling

const HTTP_TOKEN_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
if (!HTTP_TOKEN_RE.test(method) || method === "") {
  throw new Error(`Invalid HTTP method: ${JSON.stringify(method)}`);
}
const req = new Request(url, { method });

Type guard

const HTTP_TOKEN_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
function isValidHttpMethod(m: unknown): m is string {
  return typeof m === "string" && HTTP_TOKEN_RE.test(m);
}

Try / catch

try {
  new Request(url, { method });
} catch (err) {
  if (err instanceof TypeError && err.message === "Method is not valid") {
    // sanitize: fall back to a safe default method
    new Request(url, { method: "GET" });
  } else throw err;
}

Prevention

When it happens

Trigger: new Request(url, { method: "" }); method: "GET /path"; method: "POST(json)"; method with a trailing newline or any non-token character; methods read from unsanitized config or headers.

Common situations: Building the method from user input or a template string; empty-string defaults from optional config (config.method ?? "" ); method strings transported through systems that append whitespace or CRLF.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/f635d40c630b3352. Report an issue: GitHub.

Appendix: source

Thrown at ext/fetch/23_request.js:273

  "get": "GET",
  "HEAD": "HEAD",
  "head": "HEAD",
  "OPTIONS": "OPTIONS",
  "options": "OPTIONS",
  "PATCH": "PATCH",
  "POST": "POST",
  "post": "POST",
  "PUT": "PUT",
  "put": "PUT",
};

/**
 * @param {string} m
 * @returns {string}
 */
function validateAndNormalizeMethod(m) {
  if (RegExpPrototypeExec(HTTP_TOKEN_CODE_POINT_RE, m) === null) {
    throw new TypeError("Method is not valid");
  }
  const upperCase = StringPrototypeToUpperCase(m);
  switch (upperCase) {
    case "DELETE":
    case "GET":
    case "HEAD":
    case "OPTIONS":
    case "POST":
    case "PUT":
      return upperCase;
    case "CONNECT":
    case "TRACE":
    case "TRACK":
      throw new TypeError("Method is forbidden");
  }
  return m;
}

View on GitHub (pinned to 9ad36f7a2c)