{"record":{"id":"dae033a1d177c9a7","repo":"basecamp/trix","slug":"unserializable-object","errorCode":null,"errorMessage":"unserializable object","messagePattern":"unserializable object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"action_text-trix/app/assets/javascripts/trix.js","lineNumber":9924,"sourceCode":"  const stringEndsWithWhitespace = string => /\\s$/.test(string);\n\n  /* eslint-disable\n      no-empty,\n  */\n  const unserializableElementSelector = \"[data-trix-serialize=false]\";\n  const unserializableAttributeNames = [\"contenteditable\", \"data-trix-id\", \"data-trix-store-key\", \"data-trix-mutable\", \"data-trix-placeholder\", \"tabindex\"];\n  const serializedAttributesAttribute = \"data-trix-serialized-attributes\";\n  const serializedAttributesSelector = \"[\".concat(serializedAttributesAttribute, \"]\");\n  const blockCommentPattern = new RegExp(\"<!--block-->\", \"g\");\n  const serializers = {\n    \"application/json\": function (serializable) {\n      let document;\n      if (serializable instanceof Document) {\n        document = serializable;\n      } else if (serializable instanceof HTMLElement) {\n        document = HTMLParser.parse(serializable.innerHTML).getDocument();\n      } else {\n        throw new Error(\"unserializable object\");\n      }\n      return document.toSerializableDocument().toJSONString();\n    },\n    \"text/html\": function (serializable) {\n      let element;\n      if (serializable instanceof Document) {\n        element = DocumentView.render(serializable);\n      } else if (serializable instanceof HTMLElement) {\n        element = serializable.cloneNode(true);\n      } else {\n        throw new Error(\"unserializable object\");\n      }\n\n      // Remove unserializable elements\n      Array.from(element.querySelectorAll(unserializableElementSelector)).forEach(el => {\n        removeNode(el);\n      });\n","sourceCodeStart":9906,"sourceCodeEnd":9942,"githubUrl":"https://github.com/basecamp/trix/blob/470040131122bd44e269b4de0f2e9557f90ec994/action_text-trix/app/assets/javascripts/trix.js#L9906-L9942","documentation":"Trix's \"application/json\" serializer only accepts a trix Document object or an HTMLElement. Any other value (string, plain object, null, undefined) cannot be serialized, so it throws. This is an API-misuse guard in serialization.js's serializers table.","triggerScenarios":"Calling serializeToContentType(value, \"application/json\") (or the serialized value passed through attachment serialization) with a value that is neither a trix Document nor an HTMLElement, e.g. a raw string of HTML or a JSON object.","commonSituations":"Passing editor.innerHTML or editor.value (strings) into the serializer instead of an element; calling internal serialization APIs directly; custom attachment serialization hooks that hand off non-DOM values; stale bundled trix.js code where callers relied on older signatures.","solutions":["Pass a trix Document (e.g. from HTMLParser.parse(...).getDocument()) or an HTMLElement to the serializer.","If you have an HTML string, wrap it first: HTMLParser.parse(htmlString).getDocument().","For editor content, use documentView.getDocument() or the editor element's public API instead of hand-built values.","Verify you are not accidentally serializing undefined/null due to an async lookup returning nothing."],"exampleFix":"// before\ntrix.serializeToContentType(editor.value, \"application/json\")\n// after\nconst doc = trix.editor.getDocument() // or HTMLParser.parse(html, \"text/html\").getDocument()\ntrix.serializeToContentType(doc, \"application/json\")","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof window.Document) && !(value instanceof window.HTMLElement)) {\n  throw new TypeError(\"serializeToContentType expects a Document or HTMLElement\")\n}","typeGuard":"function isSerializable(value) {\n  return value instanceof Document || value instanceof HTMLElement\n}","tryCatchPattern":"try {\n  return serializeToContentType(value, \"application/json\")\n} catch (e) {\n  if (e.message === \"unserializable object\") {\n    return serializeToContentType(HTMLParser.parse(String(value)).getDocument(), \"application/json\")\n  }\n  throw e\n}","preventionTips":["Always obtain values from Trix's own API (editor.getDocument(), DocumentView) rather than strings.","Type-check inputs at module boundaries before serialization.","Wrap HTML strings with HTMLParser.parse(...).getDocument()."],"tags":["serialization","type-error","trix"],"backgroundTag":"unserializable-object","analyzedSha":"470040131122bd44e269b4de0f2e9557f90ec994","analyzedAt":"2026-09-02T10:19:15.878Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}