{"record":{"id":"bd979916434228cc","repo":"denoland/deno","slug":"cannot-convert-a-symbol-value-to-a-string-bd9799","errorCode":null,"errorMessage":"Cannot convert a Symbol value to a string","messagePattern":"Cannot convert a Symbol value to a string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/webidl/00_webidl.js","lineNumber":430,"sourceCode":"\n  return x;\n};\n\nconverters[\"unrestricted double?\"] = createNullableConverter(\n  converters[\"unrestricted double\"],\n);\n\nconverters.DOMString = function (V, _prefix, _context, opts) {\n  if (typeof V === \"string\") {\n    return V;\n  } else if (V === null && opts && opts.treatNullAsEmptyString) {\n    return \"\";\n  } else if (typeof V === \"symbol\") {\n    // V8's `String(sym)` returns the symbol description rather than throwing,\n    // so we throw explicitly to match Node and other WHATWG-conformant\n    // runtimes, which use V8's native \"Cannot convert a Symbol value to a\n    // string\" message (raised by ToPrimitive on Symbols).\n    throw new TypeError(\"Cannot convert a Symbol value to a string\");\n  }\n\n  return String(V);\n};\n\nfunction isByteString(input) {\n  for (let i = 0; i < input.length; i++) {\n    if (StringPrototypeCharCodeAt(input, i) > 255) {\n      // If a character code is greater than 255, it means the string is not a byte string.\n      return false;\n    }\n  }\n  return true;\n}\n\nconverters.ByteString = (V, prefix, context, opts) => {\n  const x = converters.DOMString(V, prefix, context, opts);\n  if (!isByteString(x)) {","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/ext/webidl/00_webidl.js#L412-L448","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst scheme = Symbol('chat');\nnew WebSocket('ws://localhost', scheme); // TypeError: Cannot convert a Symbol value to a string\n\n// after\nconst scheme = 'chat';\nnew WebSocket('ws://localhost', scheme);","handlingStrategy":"type-guard","validationCode":"function toDOMString(v: unknown): string {\n  return typeof v === 'symbol' ? String(v.description ?? '') : String(v);\n}\nnew WebSocket(toDOMString(url));","typeGuard":"const isSymbol = (v: unknown): v is symbol => typeof v === 'symbol';","tryCatchPattern":"try {\n  const ws = new WebSocket(url);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('Symbol')) {\n    // a symbol leaked into a string argument - fix the value at the source\n  } else throw e;\n}","preventionTips":["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"],"tags":["webidl","type-conversion","symbol","domstring","typeerror"],"backgroundTag":"symbol-to-string-conversion","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}