{"record":{"id":"485b6c2a54cde507","repo":"linera-io/linera-protocol","slug":"chain-chain-id-doesn-t-exist-in-wallet","errorCode":null,"errorMessage":"chain {chain_id} doesn't exist in wallet","messagePattern":"chain (.+?) doesn't exist in wallet","errorType":"exception","errorClass":"JsError","httpStatus":null,"severity":"error","filePath":"web/@linera/client/src/wallet.rs","lineNumber":50,"sourceCode":"            lock: None,\n        }\n    }\n}\n\n#[wasm_bindgen]\nimpl Wallet {\n    /// Set the owner of a chain (the account used to sign blocks on this chain).\n    ///\n    /// # Errors\n    ///\n    /// If the provided `ChainId` or `AccountOwner` are in the wrong format.\n    #[wasm_bindgen(js_name = setOwner)]\n    pub async fn set_owner(&self, chain_id: JsValue, owner: JsValue) -> Result<()> {\n        let chain_id = serde_wasm_bindgen::from_value(chain_id)?;\n        let owner = serde_wasm_bindgen::from_value(owner)?;\n        self.chains\n            .mutate(chain_id, |chain| chain.owner = Some(owner))\n            .ok_or(Error::new(&format!(\n                \"chain {chain_id} doesn't exist in wallet\"\n            )))\n    }\n\n    #[must_use]\n    /// Get the name of the wallet. Wallets with different names should use different\n    /// storage; only one wallet can use the same name at a time.\n    pub fn name(&self) -> String {\n        self.default\n            .map_or_else(|| \"default\".into(), |name| name.to_string())\n    }\n\n    /// Lock the wallet, preventing anyone else from using a wallet with this name.\n    ///\n    /// If the wallet is already locked, this is a no-op.\n    ///\n    /// # Errors\n    /// If the wallet is locked elsewhere.","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/web/@linera/client/src/wallet.rs#L32-L68","documentation":"The web wallet keeps its chains in an in-memory `wallet::Memory`; `setOwner(chainId, owner)` looks the chain up with `Memory::mutate`, which returns `None` when the ChainId is unknown, and that `None` is turned into this error. It means this Wallet instance never learned about the chain — it was not created, imported, or assigned in this wallet.","triggerScenarios":"Calling `wallet.setOwner(chainId, owner)` with a ChainId that is not among the wallet's chains (typo, wrong network, chain created in a different wallet); calling it before the wallet was updated after chain creation.","commonSituations":"dApps constructing chain IDs from strings or from another user's account; mixing chain IDs from a different genesis/testnet; race where setOwner runs before the creation result is applied to the wallet.","solutions":["Confirm the chain exists in this wallet (check its chain list) and create/import it if missing.","Use the exact ChainId value returned when the chain was created or exposed as the wallet's default chain.","After creating a chain, wait for the wallet update to land before calling setOwner.","Verify the wallet was constructed with the matching genesis config for that chain."],"exampleFix":"// before\nawait wallet.setOwner(someChainIdFromString, owner); // \"chain e5-… doesn't exist in wallet\"\n\n// after\nconst known = await wallet.chains(); // or wallet default chain\nif (!known.some(c => c.equals(target))) await importOrCreateChain(target);\nawait wallet.setOwner(target, owner);","handlingStrategy":"validation","validationCode":"const known = new Set((await wallet.chains()).map(String));\nif (!known.has(String(chainId))) throw new Error(`chain ${chainId} not in wallet; create or import it first`);","typeGuard":"async function walletHasChain(wallet: Wallet, chainId: ChainId): Promise<boolean> { return (await wallet.chains()).some(c => c.equals(chainId)); }","tryCatchPattern":"try { await wallet.setOwner(chainId, owner); } catch (e) { if (/doesn't exist in wallet/i.test(e.message)) { await importOrCreate(chainId); await wallet.setOwner(chainId, owner); } else throw e; }","preventionTips":["Always pass the ChainId object returned by creation/default-chain APIs, not reconstructed strings.","Wait for wallet updates after chain creation before mutating wallet state.","Verify the wallet's genesis config matches the network the chain belongs to."],"tags":["web-client","wasm","wallet","chain-not-found","set-owner"],"backgroundTag":"unknown-chain-id","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}