{"record":{"id":"549fbc3af7aa1838","repo":"mem0ai/mem0","slug":"neptune-analytics-update-upsert-reported-failure-f","errorCode":null,"errorMessage":"Neptune Analytics update upsert reported failure for {vector_id}","messagePattern":"Neptune Analytics update upsert reported failure for (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"mem0/vector_stores/neptune_analytics.py","lineNumber":286,"sourceCode":"                \"vector_id\": vector_id\n            }\n            query_string_embedding = f\"\"\"\n            MATCH (n :{self.collection_name})\n                WHERE id(n) = $vector_id\n            WITH $embedding as embedding, n as n\n            CALL neptune.algo.vectors.upsert(n, embedding)\n            YIELD success\n            RETURN success\n            \"\"\"\n            try:\n                result = self.execute_query(query_string_embedding, para_embedding)\n                # A soft {\"success\": False} row desyncs the payload from the embedding just as\n                # much as a thrown error, so treat it as a failure and let the rollback below fire.\n                # Mirrors the TS store's assertSuccessfulResults() check (Python's\n                # _process_success_message only logs, so it cannot drive the rollback).\n                for row in result or []:\n                    if \"success\" in row and row[\"success\"] is not True:\n                        raise RuntimeError(f\"Neptune Analytics update upsert reported failure for {vector_id}\")\n            except Exception:\n                if prior_properties is not None:\n                    try:\n                        restore_query = f\"\"\"\n                        MATCH (n :{self.collection_name})\n                            WHERE id(n) = $vector_id\n                            SET n = $properties\n                        \"\"\"\n                        self.execute_query(\n                            restore_query,\n                            {\"properties\": prior_properties, \"vector_id\": vector_id},\n                        )\n                    except Exception:\n                        logger.error(\n                            f\"Neptune Analytics: failed to restore prior payload for {vector_id} \"\n                            \"after a failed vector upsert\"\n                        )\n                raise","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/vector_stores/neptune_analytics.py#L268-L304","documentation":"Neptune Analytics update() first rewrites node properties, then upserts the new embedding; the openCypher vectors.upsert call returns a per-row success flag. If the service acknowledges the query but reports success:false (throttling, transient graph state), this RuntimeError fires and the except branch rolls the node properties back to their prior state, keeping payload and embedding consistent.","triggerScenarios":"Neptune Analytics returning {success: false} from CALL neptune.algo.vectors.upsert during update(vector_id, vector, payload); commonly under server-side throttling, capacity limits, or a graph in a mutating/resizing state.","commonSituations":"Bulk memory updates hitting vector-upsert throughput limits; graph maintenance windows; intermittent failures that a plain error-based check would have silently swallowed (the code treats soft-failure as hard failure deliberately).","solutions":["Catch RuntimeError/Exception around the update and retry with backoff — the store already restored the old properties, so a retry is safe","Reduce update concurrency against the graph (batch/queue updates)","Check the graph status and server-side metrics (throttle exceptions) with aws neptune-graph get-graph","If persistent, open an AWS support case with the graph ID and timestamp"],"exampleFix":"# before\nstore.update(vid, vector=v, payload=p)\n\n# after\nfor attempt in range(3):\n    try:\n        store.update(vid, vector=v, payload=p)\n        break\n    except RuntimeError:\n        time.sleep(2 ** attempt)\nelse:\n    raise","handlingStrategy":"retry","validationCode":"# no pre-check prevents a server-side soft failure; verify graph is available first\nimport boto3\nsts = boto3.client(\"neptune-graph\")\nstate = sts.get_graph(graphIdentifier=GRAPH_ID)[\"status\"]\nif state != \"AVAILABLE\":\n    raise RuntimeError(f\"graph not available: {state}\")","typeGuard":null,"tryCatchPattern":"for attempt in range(4):\n    try:\n        store.update(vector_id=vid, vector=v, payload=p)\n        break\n    except RuntimeError as e:\n        if \"upsert reported failure\" in str(e) and attempt < 3:\n            time.sleep(2 ** attempt)  # properties were rolled back; safe to retry\n            continue\n        raise","preventionTips":["Wrap Neptune updates in bounded exponential-backoff retry — rollback makes retries idempotent","Cap concurrent update() calls (semaphore) to stay under vector-upsert throughput","Alarm on retry counts; sustained soft-failures mean capacity or graph-state problems"],"tags":["neptune","aws","throttling","retry","consistency"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}