linera-io/linera-protocol · error · JsError
chain {chain_id} doesn't exist in wallet
Error message
chain {chain_id} doesn't exist in wallet What it means
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.
Source
Thrown at web/@linera/client/src/wallet.rs:50
lock: None,
}
}
}
#[wasm_bindgen]
impl Wallet {
/// Set the owner of a chain (the account used to sign blocks on this chain).
///
/// # Errors
///
/// If the provided `ChainId` or `AccountOwner` are in the wrong format.
#[wasm_bindgen(js_name = setOwner)]
pub async fn set_owner(&self, chain_id: JsValue, owner: JsValue) -> Result<()> {
let chain_id = serde_wasm_bindgen::from_value(chain_id)?;
let owner = serde_wasm_bindgen::from_value(owner)?;
self.chains
.mutate(chain_id, |chain| chain.owner = Some(owner))
.ok_or(Error::new(&format!(
"chain {chain_id} doesn't exist in wallet"
)))
}
#[must_use]
/// Get the name of the wallet. Wallets with different names should use different
/// storage; only one wallet can use the same name at a time.
pub fn name(&self) -> String {
self.default
.map_or_else(|| "default".into(), |name| name.to_string())
}
/// Lock the wallet, preventing anyone else from using a wallet with this name.
///
/// If the wallet is already locked, this is a no-op.
///
/// # Errors
/// If the wallet is locked elsewhere.View on GitHub (pinned to 6c226ddcb3)
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.
Example fix
// before await wallet.setOwner(someChainIdFromString, owner); // "chain e5-… doesn't exist in wallet" // after const known = await wallet.chains(); // or wallet default chain if (!known.some(c => c.equals(target))) await importOrCreateChain(target); await wallet.setOwner(target, owner);
Defensive patterns
Strategy: validation
Validate before calling
const known = new Set((await wallet.chains()).map(String));
if (!known.has(String(chainId))) throw new Error(`chain ${chainId} not in wallet; create or import it first`); Type guard
async function walletHasChain(wallet: Wallet, chainId: ChainId): Promise<boolean> { return (await wallet.chains()).some(c => c.equals(chainId)); } Try / catch
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; } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Client disposed while being referenced elsewhere
- A Wasm runtime is required to load user applications. Please
- Chain {chain_id} not found.
- Wallet already exists: {}
- Missing network description
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/485b6c2a54cde507.
Report an issue: GitHub.