{"record":{"id":"41567611b5f9d35a","repo":"MemPalace/mempalace","slug":"at-boundary-r-is-before-valid-from-valid-from-r","errorCode":null,"errorMessage":"at={boundary!r} is before valid_from={valid_from!r}; an inverted interval would be invisible to every KG query","messagePattern":"at=(.+?) is before valid_from=(.+?); an inverted interval would be invisible to every KG query","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mempalace/knowledge_graph.py","lineNumber":443,"sourceCode":"                for name, eid in ((subject, sub_id), (new_obj, new_id)):\n                    conn.execute(\n                        \"INSERT OR IGNORE INTO entities (id, name) VALUES (?, ?)\",\n                        (eid, name),\n                    )\n\n                # Reject a boundary that precedes the old fact's start — an\n                # inverted interval would be invisible to every KG query.\n                rows = conn.execute(\n                    \"SELECT valid_from FROM triples \"\n                    \"WHERE subject=? AND predicate=? AND object=? AND valid_to IS NULL\",\n                    (sub_id, pred, old_id),\n                ).fetchall()\n                for row in rows:\n                    valid_from = row[\"valid_from\"]\n                    if valid_from is not None and _temporal_end_key(boundary) < _temporal_start_key(\n                        valid_from\n                    ):\n                        raise ValueError(\n                            f\"at={boundary!r} is before valid_from={valid_from!r}; \"\n                            \"an inverted interval would be invisible to every KG query\"\n                        )\n\n                # Close the open old fact at the shared boundary.\n                conn.execute(\n                    \"UPDATE triples SET valid_to=? \"\n                    \"WHERE subject=? AND predicate=? AND object=? AND valid_to IS NULL\",\n                    (boundary, sub_id, pred, old_id),\n                )\n\n                # Open the successor at the same instant (idempotent if already open).\n                existing = conn.execute(\n                    \"SELECT id FROM triples \"\n                    \"WHERE subject=? AND predicate=? AND object=? AND valid_to IS NULL\",\n                    (sub_id, pred, new_id),\n                ).fetchone()\n                if existing:","sourceCodeStart":425,"sourceCodeEnd":461,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/knowledge_graph.py#L425-L461","documentation":"Raised by KnowledgeGraph.supersede() when the `boundary` timestamp that should close the old fact precedes that old fact's stored valid_from. supersede() closes the open old triple at `boundary` and opens the successor at the same instant; a boundary before the old start would create an inverted, query-invisible interval.","triggerScenarios":"kg.supersede(\"Alice\", \"works_at\", \"Acme\", \"BizCo\", at=\"2023-01-01\") when the open Acme triple has valid_from=\"2024-01-01\".","commonSituations":"Correcting history with an effective date earlier than the originally recorded start; timezone or date-precision mismatches between the boundary and the stored start; replaying an event log out of order so a later supersede carries an earlier timestamp.","solutions":["Look up the open old-fact triple's valid_from before superseding","Set `at` to a boundary >= that valid_from (typically the real-world transition date)","If the old fact's start is itself wrong, repair the triple directly rather than superseding with an invalid boundary"],"exampleFix":"# before\nkg.supersede(\"Alice\", \"works_at\", \"Acme\", \"BizCo\", at=\"2023-01-01\")  # old fact started 2024-01-01\n\n# after\nkg.supersede(\"Alice\", \"works_at\", \"Acme\", \"BizCo\", at=\"2024-07-01\")  # boundary >= old valid_from","handlingStrategy":"validation","validationCode":"# before superseding, ensure boundary >= old fact's start\nold = kg.get_open_triple(subject, predicate, old_obj)  # returns valid_from\nif old and old.valid_from and at < old.valid_from:\n    raise ValueError(f\"boundary {at} precedes old start {old.valid_from}\")\nkg.supersede(subject, predicate, old_obj, new_obj, at=at)","typeGuard":null,"tryCatchPattern":"try:\n    kg.supersede(...)\nexcept ValueError as e:\n    if \"inverted interval\" in str(e):\n        # old fact started later than `at`; fix the boundary or repair the old triple\n        ...\n    raise","preventionTips":["Choose supersede boundaries from the same source timeline as the original facts","For out-of-order event replays, sort events by timestamp before superseding","Unit-test supersede with boundary == valid_from (allowed) and boundary < valid_from (rejected)"],"tags":["knowledge-graph","temporal","validation","supersede"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}