{"record":{"id":"4168881c532e53e2","repo":"mem0ai/mem0","slug":"expiration-date-must-be-a-valid-date-in-yyyy-mm-dd","errorCode":null,"errorMessage":"expiration_date must be a valid date in YYYY-MM-DD format.","messagePattern":"expiration_date must be a valid date in YYYY-MM-DD format\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/memory/main.py","lineNumber":438,"sourceCode":"\n\ndef _entity_collection_name(provider: str, collection_name: str) -> str:\n    separator = \"-\" if provider == \"s3_vectors\" else \"_\"\n    return f\"{collection_name}{separator}entities\"\n\n\ndef _normalize_expiration_date(value: Any) -> Optional[str]:\n    if value is None:\n        return None\n    if isinstance(value, datetime):\n        return value.date().isoformat()\n    if isinstance(value, date):\n        return value.isoformat()\n    if isinstance(value, str):\n        try:\n            return date.fromisoformat(value).isoformat()\n        except ValueError as exc:\n            raise ValueError(\"expiration_date must be a valid date in YYYY-MM-DD format.\") from exc\n    raise ValueError(\"expiration_date must be a date string in YYYY-MM-DD format.\")\n\n\ndef _payload_is_expired(payload: Optional[Dict[str, Any]]) -> bool:\n    if not payload:\n        return False\n    expiration_date = payload.get(\"expiration_date\")\n    if not expiration_date:\n        return False\n    try:\n        return date.fromisoformat(str(expiration_date)) < datetime.now(timezone.utc).date()\n    except ValueError:\n        return False\n\n\nsetup_config()\nlogger = logging.getLogger(__name__)\n","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/memory/main.py#L420-L456","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nm.add(msg, user_id=\"u1\", expiration_date=\"2026/12/31\")\n\n# after\nfrom datetime import datetime\nm.add(msg, user_id=\"u1\", expiration_date=datetime(2026, 12, 31))\n# or: expiration_date=\"2026-12-31\"","handlingStrategy":"validation","validationCode":"from datetime import date, datetime\ndef normalize_expiration(value):\n    if value is None:\n        return None\n    if isinstance(value, (datetime, date)):\n        return value.isoformat()[:10]\n    date.fromisoformat(value)  # raises early with a clear origin\n    return value","typeGuard":"def is_valid_expiration(value) -> bool:\n    if value is None:\n        return True\n    if isinstance(value, (datetime, date)):\n        return True\n    try:\n        date.fromisoformat(value)\n        return True\n    except (ValueError, TypeError):\n        return False","tryCatchPattern":null,"preventionTips":["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."],"tags":["validation","expiration","date-parsing","add"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}