github/markup · error · NotImplementedError
subclasses of GitHub::Markup::Implementation must define #re
Error message
subclasses of GitHub::Markup::Implementation must define #render
What it means
GitHub::Markup::Implementation is an abstract base class; its #render unconditionally raises NotImplementedError. Every concrete renderer (Markdown, GemImplementation, CommandImplementation, and your own subclasses) must override render(filename, content, options: {}). The base raise exists so that a forgotten override fails loudly at render time instead of silently returning garbage.
Source
Thrown at lib/github/markup/implementation.rb:24
def initialize(regexp, languages)
@regexp = regexp
if defined?(::Linguist)
@languages = languages.map do |l|
lang = Linguist::Language[l]
raise "no match for language #{l.inspect}" if lang.nil?
lang
end
end
end
def load
# no-op by default
end
def render(filename, content, options: {})
raise NotImplementedError, "subclasses of GitHub::Markup::Implementation must define #render"
end
def match?(filename, language)
if defined?(::Linguist)
languages.include? language
else
file_ext_regexp =~ filename
end
end
private
def file_ext_regexp
@file_ext_regexp ||= /\.(#{regexp})\z/
end
end
end
endView on GitHub (pinned to 76e2682193)
Solutions
- Define the method with the exact expected signature in your subclass: def render(filename, content, options: {}) ... end.
- Prefer subclassing a concrete class (CommandImplementation for shell-out renderers, GemImplementation for gem-backed ones) so render is provided.
- Add an abstractness assertion when registering: raise if impl.method(:render).owner == GitHub::Markup::Implementation, so the error surfaces at boot rather than mid-request.
Example fix
# before
class WikiImpl < GitHub::Markup::Implementation
def initialize
super(/wiki\z/, [])
end
# forgot #render
end
GitHub::Markup.markup_impl(:wiki, WikiImpl.new)
WikiImpl.new.render('a.wiki', 'text')
# => NotImplementedError: subclasses of GitHub::Markup::Implementation must define #render
# after
class WikiImpl < GitHub::Markup::Implementation
def initialize
super(/wiki\z/, [])
end
def render(filename, content, options: {})
WikiConverter.to_html(content)
end
end Defensive patterns
Strategy: type-guard
Validate before calling
# Fail at registration time, not at first render:
def register_impl(symbol, impl)
if impl.method(:render).owner == GitHub::Markup::Implementation
raise ArgumentError, "#{impl.class} does not implement #render"
end
GitHub::Markup.markup_impl(symbol, impl)
end Type guard
# Ruby method-owner guard: detects a subclass riding on the base class's abstract render.
def implements_render?(impl)
impl.is_a?(GitHub::Markup::Implementation) &&
impl.method(:render).owner != GitHub::Markup::Implementation
end Try / catch
begin
impl.render(filename, content)
rescue NotImplementedError => e
raise ArgumentError, "#{impl.class} is incomplete: #{e.message}"
end Prevention
- Subclass a concrete class (CommandImplementation, GemImplementation, Markdown) whenever possible so #render is inherited.
- Add an abstract-method unit test per custom implementation: assert it responds with real output for a sample document.
- Run a boot-time render probe for every registered implementation to catch missing overrides before traffic.
When it happens
Trigger: Defining a class < GitHub::Markup::Implementation with only match?/regexp customized and then calling impl.render(...); registering a custom implementation via markup_impl that lacks a #render method; instantiating GitHub::Markup::Implementation.new directly and calling render on it.
Common situations: Writing a custom in-process renderer for a new markup format and forgetting the render method; refactoring a subclass and accidentally renaming render to to_html; test doubles that subclass Implementation without implementing the contract.
Related errors
- stderr
- Can not render a nil.
- The '#{symbol}' symbol is already defined.
- unknown commonmarker option: #{opt.inspect}
- unknown commonmarker extension: #{ext.inspect}
AI-assisted analysis of github/markup@76e2682193 (2026-08-21).
Data as JSON: /api/errors/c025e51c84e37c25.
Report an issue: GitHub.