denoland/deno · error · TypeError
ERR_INVALID_MIME_SYNTAX
ERR_INVALID_MIME_SYNTAX
Error message
The MIME syntax for a type in "${str}" is invalid at ${invalidTypeIndex} What it means
While parsing a MIME type string (util.ts:74), the portion before '/' (the type) must be a non-empty HTTP token: after skipping leading HTTP whitespace, if no '/' exists, the type is empty, or the type contains a non-token code point, ERR_INVALID_MIME_SYNTAX is thrown naming 'type' and the offending index.
Source
Thrown at ext/node/polyfills/internal/mime.ts:74
const SOLIDUS = "/";
const SEMICOLON = ";";
function parseTypeAndSubtype(
str: string,
): [string, string, number] {
// Skip only HTTP whitespace from start
let position = safeStringSearch(str, END_BEGINNING_WHITESPACE);
// read until '/'
const typeEnd = StringPrototypeIndexOf(str, SOLIDUS, position);
const trimmedType = typeEnd === -1
? StringPrototypeSlice(str, position)
: StringPrototypeSlice(str, position, typeEnd);
const invalidTypeIndex = safeStringSearch(
trimmedType,
NOT_HTTP_TOKEN_CODE_POINT,
);
if (trimmedType === "" || invalidTypeIndex !== -1 || typeEnd === -1) {
throw new ERR_INVALID_MIME_SYNTAX("type", str, invalidTypeIndex);
}
// skip type and '/'
position = typeEnd + 1;
const type = toASCIILower(trimmedType);
// read until ';'
const subtypeEnd = StringPrototypeIndexOf(str, SEMICOLON, position);
const rawSubtype = subtypeEnd === -1
? StringPrototypeSlice(str, position)
: StringPrototypeSlice(str, position, subtypeEnd);
position += rawSubtype.length;
if (subtypeEnd !== -1) {
// skip ';'
position += 1;
}
const trimmedSubtype = StringPrototypeSlice(
rawSubtype,
0,
safeStringSearch(rawSubtype, START_ENDING_WHITESPACE),View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Validate with a token regex before parsing: /^\s*[!#$%&'*+.^_|~A-Za-z0-9-]+\//.test(str).
- Trim and sanity-check user input: require exactly one '/', non-empty type and subtype.
- Fall back to a default MIME type (e.g. application/octet-stream) when input fails validation instead of forwarding it.
Example fix
// before
const m = new MIMEType(userInput); // userInput = 'plain' or 'te xt/plain'
// after
if (!/^\s*[!#$%&'*+.^_|~A-Za-z0-9-]+\/[!#$%&'*+.^_|~A-Za-z0-9-]+\s*(;|$)/.test(userInput ?? '')) {
throw new TypeError('invalid MIME type');
}
const m = new MIMEType(userInput); Defensive patterns
Strategy: validation
Validate before calling
const MIME_RE = /^\s*[!#$%&'*+.^_|~A-Za-z0-9-]+\/[!#$%&'*+.^_|~A-Za-z0-9-]+\s*(;|$)/;
if (!MIME_RE.test(String(input ?? ''))) throw new TypeError('invalid MIME type string'); Type guard
function looksLikeMimeType(s: string): boolean {
return /^[!#$%&'*+.^_|~A-Za-z0-9-]+\/[!#$%&'*+.^_|~A-Za-z0-9-]+$/.test(s.trim().split(';')[0]);
} Try / catch
try { new MIMEType(input); } catch (e) { if (e.code === 'ERR_INVALID_MIME_SYNTAX') { return fallbackType; } throw e; } Prevention
- Validate user-supplied Content-Type/Accept values at the boundary
- Default to application/octet-stream when parsing is not guaranteed
When it happens
Trigger: Constructing MIMEType (or parsing via MIMEType.parse / node:mime polyfill used by headers such as Content-Type parsing paths) with strings like 'plain', '/json', 'te xt/plain', 'text /plain', or leading junk — the token scan NOT_HTTP_TOKEN_CODE_POINT locates the first illegal character.
Common situations: Forwarding user-supplied Content-Type/Accept values into a MIME API without validation; strings built with template literals that include a stray space or unicode char; empty type after whitespace trimming (' /plain'); data read from config with missing values yielding ''.
Related errors
- invalid ${name}, must not be infinity or NaN
- ERR_INVALID_HTTP_TOKEN
- ERR_INVALID_HTTP_TOKEN
- ERR_HTTP_INVALID_HEADER_VALUE
- ERR_STREAM_NULL_VALUES
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/9ebaed796b0ee933.
Report an issue: GitHub.