mem0ai/mem0 · error · ValueError
expiration_date must be a valid date in YYYY-MM-DD format.
Error message
expiration_date must be a valid date in YYYY-MM-DD format.
What it means
Raised by _normalize_expiration_date when the expiration_date argument to Memory.add() is a string that cannot be parsed by date.fromisoformat(). The OSS SDK supports automatic memory expiry, but only accepts a datetime/date object or a strict 'YYYY-MM-DD' string; anything else (e.g. '2026/08/14', '14-08-2026', ISO datetime with time '2026-08-14T00:00:00', or a typo) is rejected with a plain ValueError chained from the underlying parse failure.
Source
Thrown at mem0/memory/main.py:438
def _entity_collection_name(provider: str, collection_name: str) -> str:
separator = "-" if provider == "s3_vectors" else "_"
return f"{collection_name}{separator}entities"
def _normalize_expiration_date(value: Any) -> Optional[str]:
if value is None:
return None
if isinstance(value, datetime):
return value.date().isoformat()
if isinstance(value, date):
return value.isoformat()
if isinstance(value, str):
try:
return date.fromisoformat(value).isoformat()
except ValueError as exc:
raise ValueError("expiration_date must be a valid date in YYYY-MM-DD format.") from exc
raise ValueError("expiration_date must be a date string in YYYY-MM-DD format.")
def _payload_is_expired(payload: Optional[Dict[str, Any]]) -> bool:
if not payload:
return False
expiration_date = payload.get("expiration_date")
if not expiration_date:
return False
try:
return date.fromisoformat(str(expiration_date)) < datetime.now(timezone.utc).date()
except ValueError:
return False
setup_config()
logger = logging.getLogger(__name__)
View on GitHub (pinned to 001c235229)
Solutions
- Format as date-only ISO: value.strftime('%Y-%m-%d') or value.date().isoformat().
- Pass a datetime.datetime or datetime.date object and let the SDK normalize it.
- Normalize frontend input with datetime.strptime(value, '%m/%d/%Y').date().isoformat() before calling add().
- Validate with date.fromisoformat(value) in your own layer to fail with your own error message.
Example fix
# before m.add(msg, user_id="u1", expiration_date="2026/12/31") # after from datetime import datetime m.add(msg, user_id="u1", expiration_date=datetime(2026, 12, 31)) # or: expiration_date="2026-12-31"
Defensive patterns
Strategy: validation
Validate before calling
from datetime import date, datetime
def normalize_expiration(value):
if value is None:
return None
if isinstance(value, (datetime, date)):
return value.isoformat()[:10]
date.fromisoformat(value) # raises early with a clear origin
return value Type guard
def is_valid_expiration(value) -> bool:
if value is None:
return True
if isinstance(value, (datetime, date)):
return True
try:
date.fromisoformat(value)
return True
except (ValueError, TypeError):
return False Prevention
- Send date-only strings (YYYY-MM-DD) from frontends; slice ISO datetimes with [:10].
- Prefer passing datetime/date objects and let the SDK normalize.
- Validate at the form/API boundary so users get a friendly message.
When it happens
Trigger: m.add(msg, user_id='u1', expiration_date='2026/12/31') using slashes; expiration_date='31-12-2026' day-first European format; passing a full ISO datetime string (must pass a datetime object instead or date-only string); free-text like 'next year'; locale-formatted dates from a frontend.
Common situations: Frontend sending a JS Date.toISOString() string (which includes time) directly; user-typed dates in a form not normalized; date formatting with strftime('%d-%m-%Y') by mistake.
Related errors
- messages is required and cannot be undefined or null. Provid
- messages array cannot be empty. Provide at least one message
- expirationDate must be a valid date in YYYY-MM-DD format.
- VALIDATION_001
- VALIDATION_002
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/4168881c532e53e2.
Report an issue: GitHub.