Adapter Connection Failure¶
An adapter raises AdapterConnectionError on every operation. The service is returning 500s.
Symptoms¶
- All requests to routes that use a database adapter return HTTP 500
- Logs show
[postgres.connect] Cannot reach Postgresor similar port.health()returnsPluginHealth(status=PluginStatus.UNAVAILABLE, ...)- OTel spans show
StatusCode.ERRORonrepository.*.get/repository.*.create
Diagnosis¶
1. Verify the backend is reachable.
# From within the Modal container or local environment
python -c "
import asyncio, asyncpg
asyncio.run(asyncpg.connect(dsn='<DATABASE_URL>'))
print('connected')
"
2. Check health() directly via PluginRegistry.
from openframe.core.ports import Capability
import asyncio
# If you have access to the registry instance:
port = registry.get(Capability.PERSISTENCE)
health = asyncio.run(port.health())
print(health.status) # PluginStatus.READY / DEGRADED / UNAVAILABLE
print(health.message) # error detail
3. Verify env vars are present.
AdapterConfigurationError at startup (not AdapterConnectionError) means a required env var is missing — check OPENFRAME_ENV, DATABASE_URL, and any adapter-specific vars.
Recovery¶
If the backend is down: restore the backend first. The adapter's connection pool will reconnect automatically when the backend returns.
If env vars are missing: update the Modal secret, redeploy:
If a config change caused the breakage: roll back via git and redeploy:
Prevention¶
Check port.health() in the lifespan handler and refuse startup if it returns PluginStatus.UNAVAILABLE. A service that cannot reach its database should not start serving traffic.