{"record":{"id":"ecaec2dfb87bd382","repo":"HKUDS/Vibe-Trading","slug":"connection-credential-ref-does-not-match-its-local","errorCode":null,"errorMessage":"connection credential_ref does not match its local transport","messagePattern":"connection credential_ref does not match its local transport","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connections.py","lineNumber":330,"sourceCode":"            )\n        label = str(raw.get(\"label\") or profile.label).strip()\n        if (\n            not label\n            or len(label) > 80\n            or any(ord(character) < 32 for character in label)\n        ):\n            raise ValueError(\n                \"connection label must contain 1 to 80 printable characters\"\n            )\n        expected_ref = _credential_reference(profile.id, connection_id)\n        credential_ref = str(raw.get(\"credential_ref\") or expected_ref)\n        if (\n            credential_ref == CredentialStore.reference(connection_id)\n            and profile.transport != \"local_plugin\"\n        ):\n            credential_ref = expected_ref\n        if credential_ref != expected_ref:\n            raise ValueError(\n                \"connection credential_ref does not match its local transport\"\n            )\n        return TradingConnection(\n            id=connection_id,\n            profile_id=profile.id,\n            label=label,\n            credential_ref=credential_ref,\n            created_at=str(raw.get(\"created_at\") or _now()),\n        )\n\n    def _write(self, connections: list[TradingConnection]) -> None:\n        \"\"\"Atomically rewrite the registry file with owner-only permissions.\n\n        Args:\n            connections: Full set of connections to persist.\n        \"\"\"\n        self.path.parent.mkdir(parents=True, exist_ok=True)\n        descriptor, temporary = tempfile.mkstemp(","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connections.py#L312-L348","documentation":"Raised when a connection's credential_ref does not equal the deterministic reference _credential_reference(profile.id, connection_id) expected for its transport. The parser tolerates the legacy local CredentialStore.reference(connection_id) form only for local_plugin profiles (migrating it automatically); any other mismatch is rejected to prevent a connection from reading secrets scoped to a different transport/profile.","triggerScenarios":"A settings entry with a hand-edited or stale credential_ref naming another connection's or profile's secret slot, or a non-local_plugin profile still carrying the old CredentialStore.reference(connection_id) value plus a second mismatching override. Hit during _parse from list() or save().","commonSituations":"Copying a settings file between connections or profiles without updating credential_ref; changing a connection's profile in the JSON but not its credential_ref; leftover refs after a secrets-store migration or profile rename.","solutions":["Remove the credential_ref key so it defaults to the computed expected reference","Or set credential_ref to _credential_reference(profile.id, connection_id) for the entry's actual profile and id","If secrets were stored under the old reference, re-store the credentials under the expected reference (or via store.create) before fixing the JSON","Avoid hand-editing credential_ref; always create/update connections through the store API"],"exampleFix":"// before\n{\"id\": \"alpaca\", \"profile_id\": \"live-readonly\", \"credential_ref\": \"cred:other-conn\"}\n\n// after\n{\"id\": \"alpaca\", \"profile_id\": \"live-readonly\"}  // credential_ref defaults to the computed reference","handlingStrategy":"validation","validationCode":"from trading.connections import _credential_reference\nexpected = _credential_reference(profile_id, connection_id)\nif raw.get(\"credential_ref\", expected) != expected:\n    raw.pop(\"credential_ref\", None)  # let it default to the computed reference","typeGuard":null,"tryCatchPattern":"try:\n    store.save(entries)\nexcept ValueError as exc:\n    if \"credential_ref\" in str(exc):\n        for e in entries:\n            e.pop(\"credential_ref\", None)\n        store.save(entries)\n    else:\n        raise","preventionTips":["Never hand-edit credential_ref; omit it and let the store compute it","Re-create credentials through the store after changing a connection's profile","Treat credential_ref mismatches as a security signal — audit before auto-fixing"],"tags":["python","credentials","configuration","integrity-check"],"backgroundTag":"credential-reference-mismatch","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}