denoland/deno · error · TypeError
Cannot convert a Symbol value to a string
Error message
Cannot convert a Symbol value to a string
What it means
Thrown by Deno's WebIDL DOMString converter when a Symbol is passed where a string-typed (DOMString/USVString) argument is expected. Deno throws explicitly because V8's String(sym) would return the symbol description instead of failing; the message intentionally matches V8's native 'Cannot convert a Symbol value to a string' so behavior lines up with Node and other WHATWG-conformant runtimes.
Source
Thrown at ext/webidl/00_webidl.js:430
return x;
};
converters["unrestricted double?"] = createNullableConverter(
converters["unrestricted double"],
);
converters.DOMString = function (V, _prefix, _context, opts) {
if (typeof V === "string") {
return V;
} else if (V === null && opts && opts.treatNullAsEmptyString) {
return "";
} else if (typeof V === "symbol") {
// V8's `String(sym)` returns the symbol description rather than throwing,
// so we throw explicitly to match Node and other WHATWG-conformant
// runtimes, which use V8's native "Cannot convert a Symbol value to a
// string" message (raised by ToPrimitive on Symbols).
throw new TypeError("Cannot convert a Symbol value to a string");
}
return String(V);
};
function isByteString(input) {
for (let i = 0; i < input.length; i++) {
if (StringPrototypeCharCodeAt(input, i) > 255) {
// If a character code is greater than 255, it means the string is not a byte string.
return false;
}
}
return true;
}
converters.ByteString = (V, prefix, context, opts) => {
const x = converters.DOMString(V, prefix, context, opts);
if (!isByteString(x)) {View on GitHub (pinned to f7822238ca)
Solutions
- Replace the symbol argument with its string form: Symbol.keyFor(sym) ?? sym.description
- If the value may be a symbol, convert before the call: typeof v === 'symbol' ? v.description : String(v)
- Use the stack trace's converter prefix ('Failed to ...' + 'Argument N') to find exactly which argument is the symbol
Example fix
// before
const scheme = Symbol('chat');
new WebSocket('ws://localhost', scheme); // TypeError: Cannot convert a Symbol value to a string
// after
const scheme = 'chat';
new WebSocket('ws://localhost', scheme); Defensive patterns
Strategy: type-guard
Validate before calling
function toDOMString(v: unknown): string {
return typeof v === 'symbol' ? String(v.description ?? '') : String(v);
}
new WebSocket(toDOMString(url)); Type guard
const isSymbol = (v: unknown): v is symbol => typeof v === 'symbol';
Try / catch
try {
const ws = new WebSocket(url);
} catch (e) {
if (e instanceof TypeError && e.message.includes('Symbol')) {
// a symbol leaked into a string argument - fix the value at the source
} else throw e;
} Prevention
- Type WebIDL API arguments as string, never any
- Do not store option values as symbols when the API takes strings
- Check typeof before forwarding dynamic values to typed APIs
When it happens
Trigger: Any WebIDL-typed API argument converted to DOMString/USVString that receives a symbol: new WebSocket(Symbol('ws://x')) (url is USVString 'Argument 1'), timer/event APIs taking string names, header/form values funneled through string converters.
Common situations: Passing an unquoted constant that is actually a registered symbol, mixing symbol-keyed option registries with string options, forwarding any-typed values into typed APIs, accidentally passing Symbol.iterator/Symbol.toPrimitive.
Related errors
- Cannot convert a BigInt value to a number
- ${name} is not a function
- The iterator.next() method must return an object
- The iterator.return() method must return an object
- ${openContext} could not be iterated because iterator method
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/bd979916434228cc.
Report an issue: GitHub.