{"record":{"id":"cc80ed0acd94f4ca","repo":"HKUDS/Vibe-Trading","slug":"local-connection-existing-id-already-uses-profil","errorCode":null,"errorMessage":"local connection {existing.id} already uses profile {existing.profile_id}","messagePattern":"local connection (.+?) already uses profile (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connections.py","lineNumber":233,"sourceCode":"\n        Args:\n            connection_id: Identifier to resolve or create.\n            profile_id: Read-only profile the connection must use.\n            label: Human-readable name used only when creating.\n\n        Returns:\n            The existing or newly created connection.\n\n        Raises:\n            ValueError: If an existing connection with that id uses a\n                different profile, or creation fails validation.\n        \"\"\"\n        try:\n            existing = self.get(connection_id)\n        except ValueError:\n            return self.create(connection_id, profile_id, label)\n        if existing.profile_id != str(profile_id or \"\").strip().lower():\n            raise ValueError(\n                f\"local connection {existing.id} already uses profile {existing.profile_id}\"\n            )\n        return existing\n\n    def delete(self, connection_id: str) -> None:\n        \"\"\"Delete a connection and any secrets stored for it.\n\n        Args:\n            connection_id: Identifier of the connection to remove.\n\n        Raises:\n            ValueError: If no stored connection has that id.\n        \"\"\"\n        connection = self.get(connection_id)\n        fields = credential_fields(connection.profile_id)\n        self.credentials.delete(connection.id, fields)\n        self._write([row for row in self.list() if row.id != connection.id])\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connections.py#L215-L251","documentation":"Raised by ConnectionStore.ensure when you try to ensure a local trading connection exists but a connection with the same id is already stored under a different profile. The store is immutable per id: once a connection is bound to a profile (paper, live-readonly, live), re-ensuring it with a different profile_id is rejected rather than silently rebinding it.","triggerScenarios":"Calling ensure(connection_id, profile_id, ...) where get(connection_id) succeeds and existing.profile_id != the normalized new profile_id (whitespace-trimmed, lowercased). Typically happens when the user switches a settings profile and the app re-runs parse_settings/_settings_store which call ensure for the same connection id.","commonSituations":"Switching an agent from paper to live (or to live-readonly) without deleting or renaming the prior local connection; stale connections.json entries from an earlier setup; concurrent setup flows registering the same id with different defaults.","solutions":["Delete or rename the existing connection first (store.delete(connection_id)) then ensure again with the new profile","Update the stored connection entry in the connections settings file so its profile_id matches the one you are ensuring","If the existing profile is actually correct, pass that same profile_id to ensure instead of a new one","Add a pre-check: read the existing connection and surface a confirmation prompt to the user before rebinding"],"exampleFix":"// before\nstore.ensure(\"alpaca\", \"live-readonly\")  # was created as \"paper\" -> ValueError\n\n// after\ntry:\n    store.ensure(\"alpaca\", \"live-readonly\")\nexcept ValueError:\n    store.delete(\"alpaca\")\n    store.ensure(\"alpaca\", \"live-readonly\")","handlingStrategy":"validation","validationCode":"existing = None\ntry:\n    existing = store.get(connection_id)\nexcept ValueError:\n    pass\nif existing is not None and existing.profile_id != str(profile_id or \"\").strip().lower():\n    # decide: delete-and-recreate, or keep existing\n    ...","typeGuard":null,"tryCatchPattern":"try:\n    conn = store.ensure(connection_id, profile_id)\nexcept ValueError as exc:\n    if \"already uses profile\" in str(exc):\n        store.delete(connection_id)\n        conn = store.ensure(connection_id, profile_id)\n    else:\n        raise","preventionTips":["Treat connection ids as immutable once bound to a profile; derive new ids for new profiles","Wrap profile-switch flows in an explicit delete-then-create transaction","Never hand-edit profile_id in persisted connections; go through the store API"],"tags":["python","trading","connection-store","profile-mismatch"],"backgroundTag":"duplicate-resource-conflict","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}