Skip to content

dmypy 'KeyError' on recheck #20279

Open

Description

@njgrisafi

Crash Report

Running dmypy multiple times results in a KeyError. The error is always on files we exclude in our mypy.ini.

Traceback

[nick@Mac] ~/workspace/mypy-playground [bug-dmypy-key-error]
$ uv run dmypy start -- --show-traceback
Daemon started
[nick@Mac] ~/workspace/mypy-playground [bug-dmypy-key-error]
$ uv run dmypy check src/
src/mypy_playground/example.py:3: error: Name "x" already defined on line 1  [no-redef]
Found 1 error in 1 file (checked 2 source files)
[nick@Mac] ~/workspace/mypy-playground [bug-dmypy-key-error]
$ uv run dmypy recheck
src/mypy_playground/example.py:3: error: Incompatible import of "x" (imported name has type "int", local name has type "str")  [assignment]
Found 1 error in 1 file (checked 61 source files)
[nick@Mac] ~/workspace/mypy-playground [bug-dmypy-key-error]
$ uv run dmypy recheck
Daemon crashed!
Traceback (most recent call last):
  File "mypy/dmypy_server.py", line 237, in serve
  File "mypy/dmypy_server.py", line 286, in run_command
  File "mypy/dmypy_server.py", line 408, in cmd_recheck
  File "mypy/dmypy_server.py", line 629, in fine_grained_increment_follow_imports
  File "mypy/dmypy_server.py", line 768, in find_reachable_changed_modules
KeyError: 'mypy_playground.tests'

To Reproduce
Pushed example source code to https://github.com/njgrisafi/mypy-playground/ on branch bug-dmypy-key-error

See the README https://github.com/njgrisafi/mypy-playground/tree/bug-dmypy-key-error

Your Environment

  • Mypy version used: 1.18.2 & 1.16.0
  • Mypy command-line flags: dmypy start, dmypy check src/ and dmypy recheck
  • Mypy configuration options from mypy.ini (and other config files):
[mypy]
check_untyped_defs = True
ignore_missing_imports = True
no_implicit_optional = True
allow_untyped_globals = True
local_partial_types = True
enable_error_code = ignore-without-code

follow_imports = normal
warn_unused_configs = True
warn_redundant_casts = True
no_warn_no_return = True
disallow_untyped_defs = False
disable_error_code =
  has-type,
  annotation-unchecked,
  misc

mypy_path = src
files = src/mypy_playground/

exclude = (?x)(
    \./.*  # dot-prefixed files
    | tests
  ) # (intentional whitespace, otherwise it errors)


[mypy-tests.*,*.tests.*,*.unit_tests.*,*.unit_test.*,*.integration_tests.*,conftest_integration]
ignore_errors = True
follow_imports = skip
  • Python version used: 3.12.11
  • Operating system and version: macOS Tahoe 26.1

I suspect it can be related to #18906

relates to #18755

Activity

  1. CoolCat467 commented on Dec 1, 2025

    @CoolCat467
    Contributor

    I've also encountered this error using mypy 1.19.0, except instead of recheck command, happens if I check a file from one project with a relative path, then check another file from a different project with an absolute path, and then re-check the first file with the relative path again.

  2. dnguy078 commented on Aug 6, 2026

    @dnguy078

    I opened #21818 with a fix and a regression test.

    Root cause, for the record: fix_module_deps() re-derives state.dependencies
    after each follow-imports increment so it only contains IDs still in the graph,
    but it never prunes state.ancestors. When a module is dropped from the graph,
    its descendants keep a stale ancestor edge pointing at it, and
    find_reachable_changed_modules() then dereferences that ID unconditionally.

    The first recheck creates the dangling edge and the second one trips over it,
    which is why the crash needs repeated rechecks to show up.

    @CoolCat467 — the fix targets the dangling dereference itself rather than any
    one way of reaching it, so it should cover the relative/absolute path route you
    described too. If you have a moment to try the branch against your repro, that
    would be a useful confirmation, since the test in the PR only exercises the
    excluded-package case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions