{"record":{"id":"3404c34c877363b0","repo":"HKUDS/Vibe-Trading","slug":"artifact-artifact-name-already-exists-in-unive-3404c3","errorCode":null,"errorMessage":"artifact '{artifact.name}' already exists in universe '{artifact.universe}'","messagePattern":"artifact '(.+?)' already exists in universe '(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/strategy_store/store.py","lineNumber":169,"sourceCode":"        self._lock = threading.RLock()\n        self._artifacts: dict[str, Artifact] = {}\n        self._bench_results: list[BenchResult] = []\n        self._decay_snapshots: list[DecaySnapshot] = []\n        self._bench_counter: int = 0\n        self._decay_counter: int = 0\n\n    # -- Artifact CRUD -------------------------------------------------------\n\n    @_synchronized\n    def register_artifact(self, artifact: Artifact) -> str:\n        \"\"\"Register a new artifact, assigning an ID and timestamps.\n\n        Returns:\n            The assigned ``artifact_id``.\n        \"\"\"\n        for existing in self._artifacts.values():\n            if existing.name == artifact.name and existing.universe == artifact.universe:\n                raise ValueError(\n                    f\"artifact '{artifact.name}' already exists in \"\n                    f\"universe '{artifact.universe}'\"\n                )\n        # A brand-new record has no prior validation history, so its implicit\n        # \"current\" state is UNVALIDATED — registering directly with\n        # validation_status=APPROVED would skip the VALIDATED step.\n        validate_validation_status_transition(\n            ValidationStatus.UNVALIDATED, artifact.validation_status\n        )\n        now = _now_iso()\n        artifact_id = artifact.id or _new_artifact_id()\n        stored = replace(\n            artifact,\n            id=artifact_id,\n            created_at=artifact.created_at or now,\n            updated_at=now,\n        )\n        self._artifacts[artifact_id] = stored","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/strategy_store/store.py#L151-L187","documentation":"The in-memory/file strategy store enforces the same uniqueness rule as the SQLite one: register_artifact scans existing artifacts and raises ValueError when an artifact with the same name and universe is already present, before any validation-status checks run.","triggerScenarios":"Registering the same artifact twice into the same store instance (e.g. via _register_active_artifact in tests or replays), or reloading an import script without a fresh store.","commonSituations":"Notebook sessions re-running a registration cell; test fixtures that forget to reset the store; dual-writing code paths registering the active artifact again.","solutions":["Query the store for the (name, universe) pair first and update instead of re-registering","Reset/recreate the store between import runs in scripts and tests"],"exampleFix":"# before\nstore.register_artifact(artifact)\n# after\nexisting = next((a for a in store._artifacts.values() if a.name == artifact.name and a.universe == artifact.universe), None)\nif existing is None:\n    store.register_artifact(artifact)","handlingStrategy":"try-catch","validationCode":"dup = any(a.name == artifact.name and a.universe == artifact.universe for a in store._artifacts.values())\nif not dup:\n    store.register_artifact(artifact)","typeGuard":null,"tryCatchPattern":"try:\n    store.register_artifact(artifact)\nexcept ValueError as e:\n    if 'already exists' in str(e): pass  # idempotent re-registration\n    else: raise","preventionTips":["Reset stores between test cases and notebook re-runs","Check for the (name, universe) pair before registering","Treat register as create-only; use update for changes"],"tags":["python","duplicate","model-registry","in-memory-store"],"backgroundTag":"unique-constraint-violation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}