Skip to main content

flake8-errmsg

Actions Status PyPI version PyPI platforms

Intro

A checker for Flake8 that helps format nice error messages. The checks are:

  • EM101: Check for raw usage of a string literal in Exception raising.
  • EM102: Check for raw usage of an f-string literal in Exception raising.
  • EM103: Check for raw usage of .format on a string literal in Exception raising.
  • EM104: Check for missing parentheses for built-in exceptions.
  • EM105: Check for missing message for built-in exceptions.
  • EM106: Check for walrus assignment inside a raise call's arguments.

The issue is that Python includes the line with the raise in the default traceback (and most other formatters, like Rich and IPython to too). That means a user gets a message like this:

sub = "Some value"
raise RuntimeError(f"{sub!r} is incorrect")
Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise RuntimeError(f"{sub!r} is incorrect")
RuntimeError: 'Some value' is incorrect

If this is longer or more complex, the duplication can be quite confusing for a user unaccustomed to reading tracebacks.

While if you always assign to something like msg, then you get:

sub = "Some value"
msg = f"{sub!r} is incorrect"
raise RuntimeError(msg)
Traceback (most recent call last):
  File "tmp.py", line 3, in <module>
    raise RuntimeError(msg)
RuntimeError: 'Some value' is incorrect

Now there's a simpler traceback and no double message. If you have a long message, this also often formats better when using Black, too.

Reminder: Libraries should produce tracebacks with custom error classes, and applications should print nice errors, usually without a traceback, unless something unexpected occurred. An app should not print a traceback for an error that is known to be triggerable by a user.

Options

There is one option, --errmsg-max-string-length, which defaults to 0 but can be set to a larger value. The check will ignore string literals shorter than this length. This option is supported in configuration mode as well. This will only affect string literals and not f-strings. This option is also supported when running directly, without Flake8.

Usage

Just add this to your .pre-commit-config.yaml flake8 check under additional_dependencies. If you use extend-select, you should need no other config.

You can also manually run this check (without Flake8's noqa filtering) via script entry-point (pipx run flake8-errmsg <files>) or module entry-point (python -m flake8_errmsg <files> when installed).

FAQ

Q: Why Python 3.10+ only?
A: This is a static checker and for developers. Developers and static checks should be on 3.10 already. And I was lazy and match statements are fantastic for this sort of thing. And the AST module changed in 3.8 anyway. Use Ruff (which contains the checks from this plugin) if you need to run on older versions.

Q: What other sorts of checks are acceptable?
A: Things that help with nice errors. For example, maybe requiring raise SystemExit(n) over sys.exit, exit, etc. Possibly adding a check for warnings.warn without setting stacklevel to something (usually 2).

Metadata

Release files for flake8-errmsg 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flake8-errmsg 0.7.0
File Size Uploaded
flake8_errmsg-0.7.0.tar.gz 14.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flake8-errmsg 0.7.0
File Interpreter ABI Platform
flake8_errmsg-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.4 kB

Release files / flake8_errmsg-0.7.0.tar.gz

Download URL flake8_errmsg-0.7.0.tar.gz
Size 14.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0af7480d4a892c94e7b399ecd38ea4b1889e2c7c8b398080c4c6e756cbacbe95
BLAKE2b-256 checksum
How to use checksums
8590be4b2ebfe475a6429dc15fb183abcf9d177dd2320853fca6b5c1b5448812
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 18, 2026.

Transparency log

Release files / flake8_errmsg-0.7.0-py3-none-any.whl

Download URL flake8_errmsg-0.7.0-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
406c35d07fc7edc4deb2091e0d9a7177a2102d304f58d56ef18f782834a959f0
BLAKE2b-256 checksum
How to use checksums
62472d71411967eabc97dc520fc80dc9ea275b07c0357c290e0e8ca1829bc448
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page