Valkyrian Labs logo

Troubleshooting

Diagnose common Payload Markdown setup, rendering, directive, styling, and migration issues.

Troubleshooting

The Field Does Not Appear

Check the collection entry:

1payloadMarkdown({2  collections: {3    posts: true,4  },5})

If the collection already has a blocks field, true installs the Markdown block into that field instead of adding a standalone content field. Set installField: true when you want both.

1payloadMarkdown({2  collections: {3    pages: {4      installField: true,5      installIntoBlocks: true,6    },7  },8})

Collection Config Is Not Applied

Pass collectionSlug when rendering directly:

1<MarkdownRenderer collectionSlug="posts" markdown={post.content} />

Without collectionSlug, the renderer can only use global defaults and direct props.

Markdown Blocks Render Empty

MarkdownBlockComponent expects block data as props:

1<MarkdownBlockComponent {...block} collectionSlug="pages" />

Do not pass the data as block={block} unless your wrapper component unwraps it before calling MarkdownBlockComponent.

Styles Are Missing

Confirm Tailwind scans the package output and your source-defined theme classes:

1@import "tailwindcss";2@plugin "@tailwindcss/typography";3 4@source "../node_modules/payload-markdown/dist";

Installed the scoped package? Point @source at ../node_modules/@valkyrianlabs/payload-markdown/dist instead.

If custom directive theme classes are generated dynamically, Tailwind may not see them. Keep complete class strings in source config.

Code Blocks Are Plain Text

Confirm the language is loaded in code.langs:

1import { DEFAULT_CODE_LANGS, payloadMarkdown } from 'payload-markdown'2 3payloadMarkdown({4  code: {5    langs: [...DEFAULT_CODE_LANGS, 'go'],6  },7})

Unknown language fences fall back safely, but they will not receive language-specific token colors.

Line Numbers Do Not Show

Line numbers require enhanced code rendering:

1payloadMarkdown({2  code: {3    enhanced: true,4    lineNumbers: true,5  },6})

When enhanced is false, line numbers are disabled even if lineNumbers is true.

A Directive Warns But Still Renders

Directive diagnostics are non-fatal. Invalid values fall back safely. Examples:

  • invalid :::cards{columns="wide"} falls back to 3
  • invalid :::toc{depth="20"} falls back to 3
  • unknown callout variants fall back to note
  • invalid tabs defaults fall back to the first tab
  • unknown themes fall back to the directive group's default theme

Tabs Do Not Preserve URL State

Tabs are progressively enhanced in the rendered page, but they do not currently sync state to the URL hash or across pages.

Raw HTML Does Not Render Exactly As Authored

The renderer parses raw HTML but sanitizes final output. Unsupported or unsafe HTML is removed, and authored inline style attributes are stripped.

Use Markdown and directives for content structure. Use source-defined directive themes for styling.

Runtime Settings Are Not Initialized

Runtime helpers that read plugin settings require payloadMarkdown(...) to run first. Include the plugin in the Payload config before using helpers that rely on global plugin settings.

Error shape

If settings are missing, getPayloadMarkdownSettings() throws an error that says settings have not been initialized and points back to adding payloadMarkdown(...) to the Payload plugins array.

Duplicate Copies Warning

Duplicate copies of payload-markdown are loaded in this process means two different versions of the package were imported, typically because another plugin installed its own copy. Settings are still shared between the copies, but each copy renders with its own code. Install one version, for example by aligning the dependency ranges or with a package manager override. Installing both payload-markdown and @valkyrianlabs/payload-markdown also loads two copies: keep one name.

MCP: Invalid Relationship To users

InvalidFieldRelationship: Field User has invalid relationship 'users' after adding mcpPlugin means the config relied on Payload's implicit users collection. The MCP API key collection is also an auth collection, so Payload no longer adds the default one. Define it explicitly and set admin.user:

1export default buildConfig({2  admin: { user: 'users' },3  collections: [{ slug: 'users', admin: { useAsTitle: 'email' }, auth: true, fields: [] }],4})

MCP: Agent Gets forbidden

The markdown tools need the API key's Find (read) or Update (write, publish) checkbox for the collection or global, in addition to the user's Payload access. The checkboxes only exist for collections and globals exposed in mcpPlugin({ collections, globals }). If you registered payloadMarkdownMcpTools() without withPayloadMarkdownMcp(), the key settings are not on the request: use the wrapper, or pass access: 'user'.

MCP: Writes Fail With validation_failed

Nothing was saved. The error's details lists each edit's diagnostics with line and column; the most common causes are theme names, icons or code languages the site does not have. Agents should call markdownGuide for the site's real values and markdownValidate before writing.