fix: resolve asyncpg str vs datetime TypeError in invite key creation#315
Conversation
The type hints for expires_at parameter in insert_invite_key were str|None, but asyncpg expects datetime.datetime for TIMESTAMPTZ columns. This caused engram_init to fail with asyncpg.exceptions.DataError. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
server.py (engram_status, engram_init) and engine.py (rotate_invite_key) called .isoformat() on expiry datetimes, converting them to str. asyncpg then rejected these strings for TIMESTAMPTZ columns. The storage layer now receives raw datetime objects, matching asyncpg's expectations. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
|
Someone is attempting to deploy a commit to the agentscreator's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughStorage interfaces and implementations updated to accept ChangesInvite key expiration timestamp handling
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Summary
Fixes
asyncpg.exceptions.DataErrorwhen callingengram_init/engram_status/rotate_invite_key— the expiry datetime was serialized to an ISO string via.isoformat(), but asyncpg'sTIMESTAMPTZcolumns expect adatetime.datetimeobject.Root Cause
Three call sites called
.isoformat()on the expiry datetime before passing it to storage:server.py:engram_init(L532)server.py:engram_status(L361)engine.py:rotate_invite_key(L3072)Additionally, the type hints in
storage.py(base + SQLiteStorage) andpostgres_storage.pydeclaredexpires_at: str | None, misleading callers into thinking strings were acceptable for the Postgres backend.Changes
Commit 1 — Type hints
storage.py:Storage.insert_invite_key(base class) +SQLiteStorage.insert_invite_key:expires_at: str | None→datetime | Nonepostgres_storage.py:PostgresStorage.insert_invite_key:expires_at: str | None→datetime | NoneCommit 2 — Call sites
server.pylines 361, 532: removed.isoformat()engine.pyline 3072: removed.isoformat()Why SQLiteStorage still has
.isoformat()SQLite uses TEXT columns, so the SQLiteStorage implementation correctly continues to call
.isoformat()internally — that's its concern, not the caller's. The interface now accurately reflects both backends' requirements.Verification
datetime | None(notstr | None).isoformat()calls remain in the Postgres-bound insert_invite_key paths.isoformat()for TEXT column storageSummary by CodeRabbit