pypa/pip · error · ClassNotFound

no lexer for mimetype

Error message

no lexer for mimetype {_mime!r} found

What it means

Raised by get_lexer_for_mimetype() as a ClassNotFound when neither any builtin lexer (iterated via LEXERS.values() mimetypes, lines 239-243) nor any plugin lexer (lines 244-246) has _mime in its mimetypes list. The mimetype simply is not registered with any known lexer.

Solutions

  1. Strip Content-Type parameters before calling: _mime = header.split(';')[0].strip().
  2. Cross-check the mimetype against get_all_lexers() to see which mimetypes are actually registered.
  3. Fall back to get_lexer_by_name() with a sensible default alias if the mimetype lookup fails.

Example fix

// before
lexer = get_lexer_for_mimetype(content_type)  # 'text/x-python; charset=utf-8'

// after
mime = content_type.split(';')[0].strip()
lexer = get_lexer_for_mimetype(mime)
Defensive patterns

Strategy: validation

Validate before calling

from pygments.lexers import get_all_lexers
def known_mimetypes():
    return {m for *_, mimes in get_all_lexers() for m in mimes}
def is_known_mime(mime):
    return mime in known_mimetypes()

Try / catch

from pygments.lexers import get_lexer_for_mimetype, get_lexer_by_name
from pygments.util import ClassNotFound
try:
    lexer = get_lexer_for_mimetype(mime)
except ClassNotFound:
    lexer = get_lexer_by_name('text')

Prevention

When it happens

Trigger: Calling get_lexer_for_mimetype('application/x-my-format') where that mimetype is declared by no lexer; passing a mimetype with incorrect casing or a trailing parameter that does not exactly match a registered entry.

Common situations: Web apps reading Content-Type headers and passing the raw value (including charset params like 'text/plain; charset=utf-8') directly; typos in the mimetype string; a mimetype that exists in a newer Pygments version than the vendored one bundled in pip.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/82d552de11478baa. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/pygments/lexers/__init__.py:247


def get_lexer_for_mimetype(_mime, **options):
    """
    Return a `Lexer` subclass instance that has `mime` in its mimetype
    list. The lexer is given the `options` at its instantiation.

    Will raise :exc:`pygments.util.ClassNotFound` if not lexer for that mimetype
    is found.
    """
    for modname, name, _, _, mimetypes in LEXERS.values():
        if _mime in mimetypes:
            if name not in _lexer_cache:
                _load_lexers(modname)
            return _lexer_cache[name](**options)
    for cls in find_plugin_lexers():
        if _mime in cls.mimetypes:
            return cls(**options)
    raise ClassNotFound(f'no lexer for mimetype {_mime!r} found')


def _iter_lexerclasses(plugins=True):
    """Return an iterator over all lexer classes."""
    for key in sorted(LEXERS):
        module_name, name = LEXERS[key][:2]
        if name not in _lexer_cache:
            _load_lexers(module_name)
        yield _lexer_cache[name]
    if plugins:
        yield from find_plugin_lexers()


def guess_lexer_for_filename(_fn, _text, **options):
    """
    As :func:`guess_lexer()`, but only lexers which have a pattern in `filenames`
    or `alias_filenames` that matches `filename` are taken into consideration.

View on GitHub (pinned to f399c37189)