--collect-all / collect_submodules() silently drops a package's entire subtree when a submodule raises anything other than ImportError at import time — no warning, no error, no trace

Author: kdschlosserCreated Aug 3, 2026Updated Aug 4, 2026
Labelstriage

Description of the issue

collect_submodules() (invoked via --collect-all=<package>), when it recursively imports packages to enumerate their submodules, only produces a diagnostic when the import raises ImportError (or a subclass, e.g. ModuleNotFoundError):

WARNING: Failed to collect submodules for 'pkg.sub' because importing
'pkg.sub' raised: ModuleNotFoundError: No module named 'whatever'

If the import instead raises any other exception type (TypeError, AttributeError, ValueError, etc.), nothing is printed at all — no warning, no error, no line in warn-<app>.txt. The failing package (and everything under it) is simply absent from the build, and the walk continues on to the next sibling as if that package never existed. The build itself reports success.

This turned what should have been an immediate, loud, build-time failure into a runtime ModuleNotFoundError in the frozen application, discovered only after installing and launching it — with nothing in the build log pointing at the cause. We spent a long time bisecting ~600 auto-discovered submodules to find the actual TypeError buried three import-frames deep, precisely because PyInstaller gave no indication that anything had gone wrong during collection.

Since ImportError already gets a clear, explicit warning, silently ignoring every other exception type looks like an oversight in the onerror handling rather than intentional behavior.

Context information (for bug reports)

  • Output of pyinstaller --version: 6.19.0

  • Version of Python: 3.11.14

  • Platform: Windows 11 (10.0.22621), English language settings

  • How you installed Python: python.org installer

  • Did you also try this on another platform? Does it work there? Not yet tested on another platform.

  • try the latest development version (tested against the pinned 6.19.0 release only so far)

  • follow all the instructions in our "If Things Go Wrong" Guide — n/a: this is not a "my frozen exe won't run" issue, it's a missing-diagnostic issue in the build tool itself (see below)

Make sure everything is packaged correctly

  • start with clean installation
  • use the latest development version
  • Run your frozen program from a command window (shell) — this is how the resulting ModuleNotFoundError was originally discovered
  • Package your program in --onedir mode
  • Package without UPX — not applicable, issue reproduces without UPX involved
  • Repackage in verbose/debug mode — not yet tried; given the bug is that PyInstaller's own collection-phase diagnostics are silently skipped (not a runtime bootloader issue), --debug may not surface it either, but happy to test if useful

A minimal example program which shows the error

This reproduces the underlying defect without needing our real (Cython-compiled) codebase — any non-ImportError exception at import time triggers it:

mypkg/__init__.py                  # empty

mypkg/sub/__init__.py:
    from . import bad
    from . import good

mypkg/sub/bad.py:
    raise TypeError('simulated non-ImportError failure at import time')

mypkg/sub/good.py:
    pass

myscript.py:
    import mypkg

Build with:

bash
pyinstaller --collect-all=mypkg --onedir myscript.py

Expected: either the build fails with the TypeError surfaced, or at minimum PyInstaller prints the same class of warning it prints for ImportError: Failed to collect submodules for 'mypkg.sub' because importing 'mypkg.sub' raised: TypeError: ...

Actual: no mention of mypkg.sub anywhere in the build log or in warn-myscript.txt. dist/myscript/mypkg/ does not contain sub/ at all — including good.py, which itself imports fine and has nothing wrong with it, but never gets a chance to be collected because its sibling bad.py blew up mypkg.sub's own __init__.py first.

Stacktrace / full error message

This is the real-world exception from our actual project (a Cython-compiled extension enforcing a PEP 484 annotation against its default value at module-init time) that triggered the silent drop. The key point isn't the exception itself — it's that this traceback never appears anywhere in PyInstaller's build output; we only obtained it by importing the package by hand, outside of PyInstaller, after noticing the package was missing from the frozen app:

Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "harness_designer/database/project_db/__init__.py", line 3, in <module>
    from . import pjt_bases as _pjt_bases
  File "harness_designer/database/project_db/pjt_bases.py", line 886, in init harness_designer.database.project_db.pjt_bases
  File "harness_designer/database/project_db/pjt_note.py", line 136, in init harness_designer.database.project_db.pjt_note
TypeError: Expected bytes, got int

By contrast, a sibling package in the same build that failed with ModuleNotFoundError (an ImportError subclass) did get reported correctly:

WARNING: Failed to collect submodules for 'harness_designer.ray_tracing' because
importing 'harness_designer.ray_tracing' raised: ModuleNotFoundError: No module
named 'bvh_fast'

That asymmetry — one exception family gets a clear warning, every other exception family gets total silence — is the bug being reported here.

Please also see https://github.com/pyinstaller/pyinstaller/wiki/How-to-Report-Bugs for more about what would use to solve the issue.