Skip to content

[amplifier-core] Module loader reports misleading error when import fails deep in dependency chain #226

@michaeljabbour

Description

@michaeljabbour

Bug Description

When a module fails to load due to a dependency error deep in the import chain, the loader in amplifier-core reports the wrong error message. Instead of surfacing the root cause, it reports the top-level import failure, making debugging nearly impossible.

Reproduction

The error occurs when provider-anthropic tries to load in a sub-agent session:

Failed to load module 'provider-anthropic': Module 'provider-anthropic' failed validation:
FAILED: 0/1 checks passed (1 errors, 0 warnings).
Errors: module_importable: Failed to import module:
  cannot import name 'PROVIDER_THROTTLE' from 'amplifier_core.events'

The reported cause: PROVIDER_THROTTLE doesn't exist in amplifier_core.events
The actual cause: pydantic_core._pydantic_core native extension can't load (Python version mismatch between system Python 3.14 and uv tool env Python 3.12)

The full import chain:

amplifier_core.events
  → amplifier_core.__init__
    → amplifier_core.coordinator
      → amplifier_core.hooks
        → amplifier_core.models
          → pydantic
            → pydantic_core._pydantic_core  ← ACTUAL FAILURE (ModuleNotFoundError)

Python collapses this into an ImportError on the top-level import (PROVIDER_THROTTLE), hiding the real problem 5 levels deep.

Impact

  • The error message says a constant is missing from amplifier_core.events — but it's actually there in the source
  • A developer investigating this would look at events.py, find PROVIDER_THROTTLE present, and be completely confused
  • The actual fix (reinstall pydantic-core or fix Python version) is invisible from the error message
  • When this happens during delegate(), the sub-agent fails with RuntimeError: No providers mounted — also misleading

Suggested Fix

In amplifier_core/loader.py's _validate_module method, catch the ImportError and include the full exception chain:

# Current (misleading):
except ImportError as e:
    errors.append(f"Failed to import module: {e}")

# Proposed (includes root cause):
except ImportError as e:
    import traceback
    chain = traceback.format_exception(e)
    root_cause = e
    while root_cause.__cause__:
        root_cause = root_cause.__cause__
    errors.append(
        f"Failed to import module: {e}"
        f"\n  Root cause: {type(root_cause).__name__}: {root_cause}"
    )

This would produce:

Failed to import module: cannot import name 'PROVIDER_THROTTLE' from 'amplifier_core.events'
  Root cause: ModuleNotFoundError: No module named 'pydantic_core._pydantic_core'

Secondary Issue

There may also be a related issue where sub-agent sessions spawned via delegate() resolve to the system Python (3.14) instead of the uv tool environment's Python (3.12), causing native extensions compiled for 3.12 (.cpython-312-darwin.so) to fail to load. This is what triggers the pydantic_core failure in the first place. The misleading error message makes this Python version mismatch very hard to diagnose.

Environment

  • amplifier-core: 1.0.0
  • provider-anthropic: 1.0.0
  • pydantic: 2.12.5 / pydantic-core: 2.41.5
  • uv tool env Python: 3.12.10
  • System Python: 3.14.2
  • macOS arm64 (26.3)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions