-
Notifications
You must be signed in to change notification settings - Fork 364
Description
🐛 Bug
When running aim up, a TypeError is raised from SQLAlchemy's create_engine. This happens because pool_size and max_overflow arguments are passed to create_engine for an SQLite database, which defaults to using NullPool and does not accept these arguments.
This issue appears to have been introduced in a version after 3.27.0, as that version did not specify these pooling arguments.
The error is present in both aim/web/api/db.py and aim/storage/structured/db.py.
TypeError: Invalid argument(s) 'pool_size','max_overflow' sent to create_engine(), using configuration SQLiteDialect_pysqlite/NullPool/Engine. Please check that the keyword arguments are appropriate for this combination of components.
To reproduce
- Install Aim ~=3.28.0 or ~=3.29.0.
- Run
aim initin a directory. - Run
aim up. - See the error below.
Expected behavior
The aim up command should start the Aim UI server without raising a TypeError.
Environment
- Aim 3.28.0, 3.29.1
- Python 3.12
- pip 24.3.1
- sqlalchemy v1.4.13
- OS Linux (Docker)
Full dependency tree (output from uv tree):
aim v3.29.1
├── aim-ui v3.29.1
├── aimrecords v0.0.7
│ └── base58 v2.0.1
├── aimrocks v0.5.2
├── aiofiles v24.1.0
├── alembic v1.6.0
│ ├── mako v1.3.10
│ │ └── markupsafe v3.0.2
│ ├── python-dateutil v2.9.0.post0
│ │ └── six v1.17.0
│ ├── python-editor v1.0.4
│ └── sqlalchemy v1.4.13
│ └── greenlet v3.2.3
├── boto3 v1.39.3
│ ├── botocore v1.39.3
│ │ ├── jmespath v1.0.1
│ │ ├── python-dateutil v2.9.0.post0
│ │ └── urllib3 v2.4.0
│ ├── jmespath v1.0.1
│ └── s3transfer v0.13.0
│ └── botocore v1.39.3
├── cachetools v4.2.4
├── click v8.1.8
├── cryptography v45.0.5
│ └── cffi v1.17.1
│ └── pycparser v2.22
├── fastapi v0.116.0
│ ├── pydantic v2.11.5
│ │ ├── annotated-types v0.7.0
│ │ ├── pydantic-core v2.33.2
│ │ │ └── typing-extensions v4.14.0
│ │ ├── typing-extensions v4.14.0
│ │ └── typing-inspection v0.4.1
│ │ └── typing-extensions v4.14.0
│ ├── starlette v0.46.2
│ │ └── anyio v4.9.0
│ │ ├── idna v3.10
│ │ ├── sniffio v1.3.1
│ │ └── typing-extensions v4.14.0
│ └── typing-extensions v4.14.0
├── filelock v3.18.0
├── jinja2 v3.1.6
│ └── markupsafe v3.0.2
├── numpy v2.3.0
├── packaging v25.0
├── pillow v11.2.1
├── psutil v7.0.0
├── python-dateutil v2.9.0.post0
├── pytz v2020.1
├── requests v2.32.3
│ ├── certifi v2025.4.26
│ ├── charset-normalizer v3.4.2
│ ├── idna v3.10
│ └── urllib3 v2.4.0
├── restrictedpython v8.0
├── sqlalchemy v1.4.13
├── tqdm v4.67.1
├── uvicorn v0.35.0
│ ├── click v8.1.8
│ └── h11 v0.16.0
├── watchdog v6.0.0
└── websockets v15.0.1
Additional context
A potential fix is to explicitly set a compatible connection pool, like QueuePool, when creating the engine for SQLite, or to remove the pool_size and max_overflow arguments if pooling is not intended for the SQLite connection.
I've tried this and it appears to work:
from sqlalchemy.pool import QueuePool
engine = create_engine(
get_db_url(),
# ... other args
poolclass=QueuePool, # Explicitly set the pool class
pool_size=10,
max_overflow=20,
)I.e. it starts, but I haven't tested the app thoroughly.