it seems like there are some ghost mark types creeping their way into my block content

9 replies
Last updated: Oct 12, 2020
anyone have any idea how to get rid of these warnings? it seems like there are some ghost mark types creeping their way into my block content
Unknown mark type "a5a909c5150a", please specify a serializer for it in the `serializers.marks` prop
Unknown mark type "80061e4e5eb1", please specify a serializer for it in the `serializers.marks` prop
Unknown mark type "1df06a28145f", please specify a serializer for it in the `serializers.marks` prop
(looks like this warning comes from block-content-to-hyperscript here
https://github.com/sanity-io/block-content-to-hyperscript/blob/c8c18eb3adc3ca67daba80ad822a2eb21a2f6a3c/src/serializers.js#L31 )
AI Update

Good news - these "ghost marks" with hex IDs are a common issue with leftover annotation references in your Portable Text content! Here's what's happening and how to fix it.

The Problem

When you add an annotation (like a link) to text in Portable Text, Sanity creates two things:

  1. A mark on the text span (e.g., marks: ["a5a909c5150a"])
  2. A corresponding entry in the markDefs array with that ID

When you remove the annotation through the editor, sometimes the mark reference gets left behind in the text span even though the markDefs entry is gone. This creates "ghost marks" that your serializer doesn't recognize.

The Solution: Clean Your Content

You need to clean up these orphaned mark references from your documents. Here's a migration script approach using the Sanity migration toolkit:

import {defineMigration, at} from 'sanity/migrate'

const cleanGhostMarks = defineMigration({
  title: 'Clean ghost marks from portable text',
  documentTypes: ['yourDocType'],
  
  migrate: {
    document(doc, context) {
      // Clean your block content field
      if (doc.yourBlockField) {
        return at('yourBlockField', cleanBlockContent(doc.yourBlockField))
      }
    }
  }
})

function cleanBlockContent(blocks) {
  return blocks.map(block => {
    if (block._type !== 'block' || !block.children) return block
    
    const validMarkKeys = new Set(
      (block.markDefs || []).map(def => def._key)
    )
    
    return {
      ...block,
      children: block.children.map(child => ({
        ...child,
        marks: (child.marks || []).filter(mark => 
          validMarkKeys.has(mark) || 
          ['strong', 'em', 'underline', 'code'].includes(mark) // keep decorators
        )
      }))
    }
  })
}

This script filters out any marks that don't have a corresponding entry in markDefs, keeping only valid decorator marks (bold, italic, etc.) and annotations.

Quick Fix: Add Default Serializers

While you work on cleaning the data, you can suppress the warnings by adding a catch-all serializer:

// For @sanity/block-content-to-react (deprecated)
<BlockContent
  blocks={content}
  serializers={{
    marks: {
      // Your existing serializers...
      // These hex IDs will just render as plain text
      'a5a909c5150a': ({children}) => children,
      '80061e4e5eb1': ({children}) => children,
      '1df06a28145f': ({children}) => children,
    }
  }}
/>

// For @portabletext/react (recommended)
<PortableText
  value={content}
  components={{
    marks: {
      // Add serializers for each ghost mark
      'a5a909c5150a': ({children}) => <>{children}</>,
      '80061e4e5eb1': ({children}) => <>{children}</>,
      '1df06a28145f': ({children}) => <>{children}</>,
    }
  }}
/>

Note: If you're still using @sanity/block-content-to-react, consider migrating to @portabletext/react as the old library is deprecated.

Prevention

To prevent this in the future:

  • Keep your Sanity Studio dependencies updated
  • If you're doing programmatic updates to Portable Text, make sure you're removing both the mark reference AND the markDefs entry
  • The newer versions of the Portable Text editor handle annotation removal more reliably

The root cause is usually from older versions of the editor or custom annotation handling code that didn't properly clean up both parts of the annotation.

Show original thread
9 replies
Ran into the exact same problem today! Suddenly I was getting all these warnings. To get rid of them, I had to copy paste the rich text into notepad to remove the formatting and then add it back into the CMS.
ohhhh wow
good to know
only way to get rid of the ghost marks
thank you
i have the exact same error but i dont know what you mean with “remove the formatting” can you elaborate maybe a bit more? that would be great
Jérôme Pott
i have the exact same error but i dont know what you mean with “remove the formatting” can you elaborate maybe a bit more?
when you copy rich text (from portable text, Word, etc.), the formatting is copied over. When you past into a Word document, you have the option to only keep the text. In the Studio you don’t have this option. The solution is to copy the text in a editor with formatting marks, like the notepad, and then copy in the rich text editor.
ah kk thanks !

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?