{"record":{"id":"26eaa03b09fae537","repo":"markedjs/marked","slug":"renderer-prop-does-not-exist","errorCode":null,"errorMessage":"renderer '${prop}' does not exist","messagePattern":"renderer '(.+?)' does not exist","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Instance.ts","lineNumber":167,"sourceCode":"                } else {\n                  extensions.startInline = [ext.start];\n                }\n              }\n            }\n          }\n          if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens\n            extensions.childTokens[ext.name] = ext.childTokens;\n          }\n        });\n        opts.extensions = extensions;\n      }\n\n      // ==-- Parse \"overwrite\" extensions --== //\n      if (pack.renderer) {\n        const renderer = this.defaults.renderer || new _Renderer<ParserOutput, RendererOutput>(this.defaults);\n        for (const prop in pack.renderer) {\n          if (!(prop in renderer)) {\n            throw new Error(`renderer '${prop}' does not exist`);\n          }\n          if (['options', 'parser'].includes(prop)) {\n            // ignore options property\n            continue;\n          }\n          const rendererProp = prop as Exclude<keyof _Renderer<ParserOutput, RendererOutput>, 'options' | 'parser'>;\n          const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;\n          const prevRenderer = renderer[rendererProp] as GenericRendererFunction;\n          // Replace renderer with func to run extension, but fall back if false\n          renderer[rendererProp] = (...args: unknown[]) => {\n            let ret = rendererFunc.apply(renderer, args);\n            if (ret === false) {\n              ret = prevRenderer.apply(renderer, args);\n            }\n            return (ret || '') as RendererOutput;\n          };\n        }\n        opts.renderer = renderer;","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/markedjs/marked/blob/9552b6bbca7f587f96b7249c5833358a17a18e2b/src/Instance.ts#L149-L185","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Rename the key to an existing renderer method (see list above); mind casing - marked uses lowercase concatenated names (listitem, tablecell, tablerow, codespan).","If you meant to render a custom token type, move it into extensions:[{ name:'yourType', renderer(token){...} }] instead of the renderer override object.","Remove non-method helper properties from the renderer object; keep helpers as closures or in a separate object."],"exampleFix":"// before — 'headingh' is not a renderer method\nmarked.use({ renderer: { headingh(token) { return `<h${token.depth}>${token.text}</h${token.depth}>`; } } });\n\n// after\nmarked.use({ renderer: { heading(token) { return `<h${token.depth}>${this.parser.parseInline(token.tokens)}</h${token.depth}>`; } } });","handlingStrategy":"validation","validationCode":"import { _Renderer } from 'marked';\nconst ALLOWED = Object.getOwnPropertyNames(_Renderer.prototype)\n  .filter(k => k !== 'constructor' && k !== 'options' && k !== 'parser');\nfor (const prop in myExt.renderer ?? {}) {\n  if (!ALLOWED.includes(prop)) {\n    throw new Error('renderer key \"' + prop + '\" is not a known renderer method; allowed: ' + ALLOWED.join(', '));\n  }\n}\nmarked.use(myExt);","typeGuard":"function isValidRendererKey(prop, rendererProto) {\n  return prop in rendererProto && !['constructor','options','parser'].includes(prop);\n}","tryCatchPattern":null,"preventionTips":["Reference the Renderer API table in marked docs for exact method names.","Annotate your override object with the RendererObject type - its keys are constrained to the renderer API so TS flags typos.","Keep the renderer override object free of helper/utility fields."],"tags":["configuration","renderer","typo","validation","marked-use"],"backgroundTag":null,"analyzedSha":"9552b6bbca7f587f96b7249c5833358a17a18e2b","analyzedAt":"2026-08-13T04:27:55.513Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}