markedjs/marked · error · Error

renderer '${prop}' does not exist

Error message

renderer '${prop}' does not exist

What it means

Thrown by Marked.use() when the renderer object you pass contains a key that is not a method or known property of the _Renderer class. Marked iterates every own enumerable key with for...in and checks prop in renderer (Instance.ts:165-167); any key not present on a _Renderer instance is rejected. Allowed method names are the public renderer methods (code, blockquote, html, heading, hr, list, listitem, checkbox, paragraph, table, tablerow, tablecell, space, def, strong, em, codespan, br, del, link, image, text) plus the ignored properties options and parser. This path overrides existing renderer methods; to render a NEW token type use extensions:[{ name, renderer }] instead.

Source

Thrown at src/Instance.ts:167

                } else {
                  extensions.startInline = [ext.start];
                }
              }
            }
          }
          if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
            extensions.childTokens[ext.name] = ext.childTokens;
          }
        });
        opts.extensions = extensions;
      }

      // ==-- Parse "overwrite" extensions --== //
      if (pack.renderer) {
        const renderer = this.defaults.renderer || new _Renderer<ParserOutput, RendererOutput>(this.defaults);
        for (const prop in pack.renderer) {
          if (!(prop in renderer)) {
            throw new Error(`renderer '${prop}' does not exist`);
          }
          if (['options', 'parser'].includes(prop)) {
            // ignore options property
            continue;
          }
          const rendererProp = prop as Exclude<keyof _Renderer<ParserOutput, RendererOutput>, 'options' | 'parser'>;
          const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;
          const prevRenderer = renderer[rendererProp] as GenericRendererFunction;
          // Replace renderer with func to run extension, but fall back if false
          renderer[rendererProp] = (...args: unknown[]) => {
            let ret = rendererFunc.apply(renderer, args);
            if (ret === false) {
              ret = prevRenderer.apply(renderer, args);
            }
            return (ret || '') as RendererOutput;
          };
        }
        opts.renderer = renderer;

View on GitHub (pinned to 9552b6bbca)

Solutions

  1. Rename the key to an existing renderer method (see list above); mind casing - marked uses lowercase concatenated names (listitem, tablecell, tablerow, codespan).
  2. If you meant to render a custom token type, move it into extensions:[{ name:'yourType', renderer(token){...} }] instead of the renderer override object.
  3. Remove non-method helper properties from the renderer object; keep helpers as closures or in a separate object.

Example fix

// before — 'headingh' is not a renderer method
marked.use({ renderer: { headingh(token) { return `<h${token.depth}>${token.text}</h${token.depth}>`; } } });

// after
marked.use({ renderer: { heading(token) { return `<h${token.depth}>${this.parser.parseInline(token.tokens)}</h${token.depth}>`; } } });
Defensive patterns

Strategy: validation

Validate before calling

import { _Renderer } from 'marked';
const ALLOWED = Object.getOwnPropertyNames(_Renderer.prototype)
  .filter(k => k !== 'constructor' && k !== 'options' && k !== 'parser');
for (const prop in myExt.renderer ?? {}) {
  if (!ALLOWED.includes(prop)) {
    throw new Error('renderer key "' + prop + '" is not a known renderer method; allowed: ' + ALLOWED.join(', '));
  }
}
marked.use(myExt);

Type guard

function isValidRendererKey(prop, rendererProto) {
  return prop in rendererProto && !['constructor','options','parser'].includes(prop);
}

Prevention

When it happens

Trigger: marked.use({ renderer:{ headingh(token){...} } }) with a typo like 'headingh'; using a method name from an older marked major version that was renamed/removed; spreading a plain object with helper properties into the renderer override; misspelling 'codespan' as 'codeSpan' or 'listitem' as 'listItem'.

Common situations: Following a blog post written for a different marked version whose renderer method names differ; adding a non-method helper field (e.g. formatDate) onto the renderer object expecting it to be ignored; casing errors on lowercased concatenated names.

Related errors


AI-assisted analysis of markedjs/marked@9552b6bbca (2026-08-13). Data as JSON: /api/errors/26eaa03b09fae537. Report an issue: GitHub.