PrefectHQ/fastmcp · error · ImportError

Failed to execute module {file_path}: {e}

Error message

Failed to execute module {file_path}: {e}

What it means

First-time import path: after building the module from the spec, `spec.loader.exec_module(module)` raised. FastMCP pops the half-initialized module from sys.modules (so retries start clean) and wraps any exception in this ImportError.

Source

Thrown at fastmcp_slim/fastmcp/server/providers/filesystem_discovery.py:276

                existing.__loader__ = spec.loader
                existing.__file__ = str(file_path)
                try:
                    spec.loader.exec_module(existing)
                except Exception as e:
                    raise ImportError(
                        f"Failed to reload module {file_path}: {e}"
                    ) from e
                return existing

            module = importlib.util.module_from_spec(spec)
            sys.modules[module_name] = module

            try:
                spec.loader.exec_module(module)
            except Exception as e:
                # Clean up sys.modules on failure
                sys.modules.pop(module_name, None)
                raise ImportError(f"Failed to execute module {file_path}: {e}") from e

            return module
        finally:
            if path_added:
                with contextlib.suppress(ValueError):
                    sys.path.remove(parent_dir)


def extract_components(module: ModuleType) -> list[FastMCPComponent]:
    """Extract all MCP components from a module.

    Scans all module attributes for instances of Tool, Resource,
    ResourceTemplate, or Prompt objects created by standalone decorators,
    or functions decorated with @tool/@resource/@prompt that have __fastmcp__ metadata.

    Args:
        module: The imported module to scan.

View on GitHub (pinned to 1f02114297)

Solutions

  1. Read the chained cause for the real exception and fix the plugin file
  2. Run `python -m py_compile plugin.py` to catch syntax errors early
  3. Move side-effectful code out of module scope into functions or `if __name__ == '__main__':`
  4. Install missing dependencies; since sys.modules is cleaned up, simply retry discovery after fixing

Example fix

// before
# plugin.py
cfg = open('/etc/missing.conf').read()  # FileNotFoundError at import
// after
# plugin.py
def load_cfg():
    return open('/etc/missing.conf').read()
Defensive patterns

Strategy: try-catch

Validate before calling

import py_compile; py_compile.compile(str(path), doraise=True)

Try / catch

try:
    mod = provider.import_module_from_file(path)
except ImportError as e:
    log.error('exec of %s failed: %s', path, e.__cause__)
    # sys.modules is cleaned up; safe to retry after fixing the file

Prevention

When it happens

Trigger: Executing a plugin file for the first time where module-level code raises anything: SyntaxError, ImportError, NameError, or a runtime error at import time.

Common situations: Newly added tool files with syntax errors; dependencies missing in the deployment env; module-level `open()`/network calls failing; Python version incompatibilities in the plugin.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/a95f4a696d051e6e. Report an issue: GitHub.