** Please make sure you read the contribution guide and file the issues in the right place. **
Describe the bug
The v0→v1 session migration tool's restricted unpickler (added in 9db48ce9, "fix(migration): restrict unpickling of v0 actions blobs") blocks builtins.getattr, and on Python 3.11 — specifically an environment with the full test extras installed, where crewai[tools] applies per the pyproject marker python_version>='3.11' and python_version<'3.12' — the pickled EventActions graph contains a getattr global. The unpickler rejects it, _safe_unpickle_actions logs a WARNING and falls back to empty actions, and migrated events silently lose requested_auth_configs and compaction.
Observable today as a deterministic unit-test failure on the py311 tox environment:
FAILED tests/unittests/sessions/migration/test_migration.py::test_migrate_from_sqlalchemy_pickle_preserves_nested_safe_actions_pickle
AssertionError: assert 'fc-auth' in {}
with this in the captured log:
WARNING ... Failed to unpickle actions for event event1: Blocked global during migration unpickle: builtins.getattr
To Reproduce
Steps to reproduce (repo at current main):
- uv venv --python "python3.11" .venv && source .venv/bin/activate && uv sync --all-extras
- pytest "tests/unittests/sessions/migration/test_migration.py::test_migrate_from_sqlalchemy_pickle_preserves_nested_safe_actions_pickle"
- Test fails as above. The same test passes on py310, py312, py313, and py314 tox environments (tox run: py310 OK, py311 FAIL, py312 OK, py313 OK, py314 OK).
Ruling out version skew: pydantic (2.12.5), fastapi (0.141.1), and google-genai (2.17.0) are identical across the py310/py311/py312 environments — the only material difference in the failing environment is the presence of crewai and its transitive dependencies, which only install on 3.11. A plausible mechanism is a pydantic plugin registered via entry points by one of those transitive dependencies altering how pydantic model instances pickle (introducing a getattr reduction), but I have not bisected the exact package.
Expected behavior
Either the migration unpickler accepts the pickle streams that pydantic models actually produce in every supported environment (so nested EventActions content survives migration), or — if builtins.getattr must stay blocked for hardening reasons — the migration should not silently degrade to {} for blobs a supported environment wrote. Silent data loss during migration is the worst outcome of the current behavior; the test correctly catches it.
Desktop:
- OS: macOS (Darwin 24.6.0)
- Python version: 3.11 (failing); 3.10/3.12/3.13/3.14 (passing)
- ADK version: current main (c5672030)
Additional context
🤖 Generated with Claude Code
** Please make sure you read the contribution guide and file the issues in the right place. **
Describe the bug
The v0→v1 session migration tool's restricted unpickler (added in 9db48ce9, "fix(migration): restrict unpickling of v0 actions blobs") blocks builtins.getattr, and on Python 3.11 — specifically an environment with the full test extras installed, where crewai[tools] applies per the pyproject marker python_version>='3.11' and python_version<'3.12' — the pickled EventActions graph contains a getattr global. The unpickler rejects it, _safe_unpickle_actions logs a WARNING and falls back to empty actions, and migrated events silently lose requested_auth_configs and compaction.
Observable today as a deterministic unit-test failure on the py311 tox environment:
FAILED tests/unittests/sessions/migration/test_migration.py::test_migrate_from_sqlalchemy_pickle_preserves_nested_safe_actions_pickle AssertionError: assert 'fc-auth' in {}with this in the captured log:
To Reproduce
Steps to reproduce (repo at current main):
Ruling out version skew: pydantic (2.12.5), fastapi (0.141.1), and google-genai (2.17.0) are identical across the py310/py311/py312 environments — the only material difference in the failing environment is the presence of crewai and its transitive dependencies, which only install on 3.11. A plausible mechanism is a pydantic plugin registered via entry points by one of those transitive dependencies altering how pydantic model instances pickle (introducing a getattr reduction), but I have not bisected the exact package.
Expected behavior
Either the migration unpickler accepts the pickle streams that pydantic models actually produce in every supported environment (so nested EventActions content survives migration), or — if builtins.getattr must stay blocked for hardening reasons — the migration should not silently degrade to {} for blobs a supported environment wrote. Silent data loss during migration is the worst outcome of the current behavior; the test correctly catches it.
Desktop:
Additional context
🤖 Generated with Claude Code