{"record":{"id":"3558ee47673f0503","repo":"basecamp/trix","slug":"unserializable-object-3558ee","errorCode":null,"errorMessage":"unserializable object","messagePattern":"unserializable object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/trix/core/serialization.js","lineNumber":32,"sourceCode":"  \"data-trix-store-key\",\n  \"data-trix-mutable\",\n  \"data-trix-placeholder\",\n  \"tabindex\",\n]\nconst serializedAttributesAttribute = \"data-trix-serialized-attributes\"\nconst serializedAttributesSelector = `[${serializedAttributesAttribute}]`\n\nconst blockCommentPattern = new RegExp(\"<!--block-->\", \"g\")\n\nconst 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\n    return document.toSerializableDocument().toJSONString()\n  },\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)","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/basecamp/trix/blob/470040131122bd44e269b4de0f2e9557f90ec994/src/trix/core/serialization.js#L14-L50","documentation":"In src/trix/core/serialization.js, the \"application/json\" serializer requires a trix Document or HTMLElement; other types throw \"unserializable object\". Strings must be parsed into a Document before serialization.","triggerScenarios":"serializeToContentType(x, \"application/json\") where x is a string, plain object, array, null, or a trix DocumentView instance rather than its Document.","commonSituations":"Passing DocumentView (the view wrapper) instead of .document; passing editor JSON strings expecting re-serialization; test fixtures using plain JS objects.","solutions":["Unwrap DocumentView: pass view.document (a trix Document) instead of the view.","Parse HTML strings with HTMLParser.parse(html).getDocument().","Pass HTMLElements directly; they are converted internally.","Assert the input type before serializing in custom pipelines."],"exampleFix":"// before\nserializeToContentType(documentView, \"application/json\")\n// after\nserializeToContentType(documentView.getDocument(), \"application/json\")","handlingStrategy":"type-guard","validationCode":"if (!(value instanceof Document) && !(value instanceof HTMLElement)) {\n  value = HTMLParser.parse(String(value ?? \"\")).getDocument()\n}","typeGuard":"const isTrixSerializable = (v) => v instanceof Document || v instanceof HTMLElement","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":["Unwrap DocumentView objects (use .getDocument()) before serializing.","Convert all string inputs via HTMLParser.parse first.","Add runtime assertions in custom serialization pipelines."],"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"}