CrewAI memory recall: "TypeError: can't subtract offset-naive and offset-aware datetimes"
CrewAI's recall scoring subtracts a naive utcnow() from your record's created_at. A timezone-aware timestamp crashes recall. Repro and workaround.
Disclosure: I work on MemorySync (I'm Mohammed, the founder). I drafted this page with AI assistance and checked it against the GitHub issue and the crewAI source listed under Sources on Nov 10, 2026. Code status: I ran the repro and the workaround offline on crewai 1.15.39 (Python 3.13, no model calls, no network). I didn't run a full crew with memory, a custom storage backend, the fix PR linked in the issue, or any MemorySync code.
Your crew's memory recall stops with:
TypeError: can't subtract offset-naive and offset-aware datetimes
That's crewAI issue #7529, "compute_composite_score crashes with TypeError on timezone-aware datetimes during memory recall". It happens when a memory record's created_at carries a timezone, for example datetime.now(timezone.utc) or a timestamp parsed from a store or API with +00:00 or Z.
MemorySync doesn't fix this bug. The crash is in crewAI's own recall scoring, and you need the workaround below with or without MemorySync.
Skip the memory plumbing around this fix. Once your records carry safe timestamps, the MemorySync CrewAI guide shows how to point CrewAI's
Memory(storage=...)at MemorySync. It doesn't change how crewAI scores records. When you're ready, see MemorySync. Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).
Status (Nov 10, 2026)
- #7529 was opened Sep 17, 2026 and is open. The reporter linked a fix PR in the thread; it isn't merged.
- It reproduces on crewai 1.15.39, the latest release on PyPI when I checked (Nov 10, 2026; uploaded Nov 9).
Step 1: Reproduce it
The issue's repro, extended with a naive timestamp for comparison:
from datetime import datetime, timezone
from crewai.memory.types import MemoryRecord, MemoryConfig, compute_composite_score
for label, ts in [("naive utc", datetime.utcnow()), ("aware utc", datetime.now(timezone.utc))]:
rec = MemoryRecord(content="User prefers Python", created_at=ts)
try:
print(label, compute_composite_score(rec, 0.85, MemoryConfig()))
except Exception as e:
print(label, type(e).__name__, e)
Output on crewai 1.15.39:
naive utc (0.8249999999943841, ['semantic', 'recency'])
aware utc TypeError can't subtract offset-naive and offset-aware datetimes
Why it happens
In crewai 1.15.39, lib/crewai/src/crewai/memory/types.py computes a record's age like this:
age_seconds = (datetime.utcnow() - record.created_at).total_seconds()
datetime.utcnow() returns a naive datetime. Python refuses to subtract an aware datetime from a naive one. MemoryRecord.created_at itself defaults to datetime.utcnow (naive), so records crewAI creates on its own are fine. The crash comes from records you build yourself, or from a storage backend that returns aware timestamps. Per the issue, compute_composite_score() runs on every memory.recall(), so one aware record is enough to break recall.
Step 2: Store naive UTC timestamps
Until the fix ships, make sure every created_at that reaches crewAI is naive UTC, which is what crewAI's own default produces:
from datetime import datetime, timezone
def to_naive_utc(d: datetime) -> datetime:
if d.tzinfo is None:
return d # assume it's already UTC, like crewAI's default
return d.astimezone(timezone.utc).replace(tzinfo=None)
rec = MemoryRecord(content="User prefers Python", created_at=to_naive_utc(datetime.now(timezone.utc)))
print(compute_composite_score(rec, 0.85, MemoryConfig()))
This ran without error on crewai 1.15.39. Where to apply it:
- Records you create yourself: pass
created_at=to_naive_utc(...), or leavecreated_atout and let crewAI use its default. - A custom storage backend: convert timestamps on the way out, in the code that builds
MemoryRecordobjects from your database rows. Postgrestimestamptz, ISO strings ending inZ, and many client libraries give you aware datetimes. - Timestamps parsed from strings:
datetime.fromisoformat("2026-10-30T10:00:00+00:00")is aware. Run it throughto_naive_utctoo.
If any of your naive timestamps are in local time rather than UTC, convert them first; otherwise the recency part of the score will be off by your UTC offset.
Step 3: Find the record that breaks recall
If recall already fails, look for records whose created_at has a tzinfo:
bad = [r for r in records if r.created_at.tzinfo is not None]
How you list records depends on your storage backend. Rewriting those timestamps with to_naive_utc and saving them again removes the crash.
Skip the plumbing with MemorySync
Disclosure: I build MemorySync.
This doesn't change the fix above: the crash is in crewAI's own scoring, so keep created_at naive UTC as in Step 2. The MemorySync CrewAI guide documents MemorySyncStorage, a CrewAI StorageBackend you pass as Memory(storage=...), so the crew's save and recall loop runs against MemorySync instead of local LanceDB files. It requires crewai 1.0+ and Python 3.10+ and lists crewai-memorysync 1.1.0. The guide doesn't say whether this changes how crewAI scores recalled records, so don't count on it to avoid this error.
From the guide:
Unverified (not run):
pip install crewai-memorysync
from crewai import Crew
from crewai.memory import Memory
from crewai_memorysync import MemorySyncStorage
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task],
memory=Memory(storage=MemorySyncStorage(user_id="support-crew")),
)
crew.kickoff()
Snippet adapted from the MemorySync CrewAI guide; I haven't run it for this page. Set MEMORYSYNC_API_KEY in the environment, as the guide says. Per the guide, user_id is the memory owner: one id per crew gives a shared knowledge base, one per end user gives memory per customer.
Try it: MemorySync is optional here: the steps above work without it. If you want the memory layer from the snippet, see MemorySync, create an API key in the dashboard and drop the snippet into your agent.
FAQ
Is this a problem with my embedder or LLM? No. The error comes from date arithmetic in the scoring step, before any model is involved. My repro ran with no model and no network.
Why does datetime.utcnow() print a deprecation warning?
It's deprecated since Python 3.12. The issue's proposed fix moves to datetime.now(timezone.utc) and normalises both sides to UTC.
Will upgrading fix it? Not as of Nov 10, 2026. The issue is open and crewai 1.15.39 still has the naive subtraction. Watch #7529 for the merged fix.
Sources
- github.com/crewAIInc/crewAI/issues/7529 (opened 2026-09-17, open, 4 comments; repro, root cause and proposed fix; read 2026-11-10)
- crewai 1.15.39 source:
crewai/memory/types.py(MemoryRecord.created_atdefault,compute_composite_score; read 2026-11-10) - Offline runs on crewai 1.15.39, Python 3.13 (2026-11-10)
- MemorySync CrewAI guide: docs.memorysync.io/guides/crewai (fetched 2026-10-30)
Try it
For an overview of MemorySync, see the MemorySync homepage.
Next step: read the MemorySync CrewAI guide, then see MemorySync. Founding offer: use code FOUNDING30 for 30% off Starter for your first 3 months (Settings → Billing).
About the author
- Building MemorySync (memorysync.io) — persistent memory infrastructure for AI agents, Cursor, and Claude Code.
Comments
Join the discussionNo comments yet. Be the first to comment.
