linera-io/linera-protocol · error · Error
No MetaMask accounts connected
Error message
No MetaMask accounts connected
What it means
share_ownership adds a new owner to the chain, which requires the chain to currently have active ownership to build a valid Ownership operation. The guard ensure!(ownership.is_active()) fails with ChainError::InactiveChain when the chain has no owners at all — there is nobody left to sign the ownership change, so the operation cannot proceed.
Source
Thrown at web/@linera/metamask/src/signer.ts:50
constructor() {
if (typeof window === "undefined" || !window.ethereum) {
throw new Error("MetaMask is not available");
}
this.provider = new ethers.BrowserProvider(window.ethereum!);
}
async sign(owner: string, value: Uint8Array): Promise<string> {
if (!window.ethereum) {
throw new Error("MetaMask is not available");
}
// Explicitly type the result and check for undefined
const accounts = (await window.ethereum.request({
method: "eth_requestAccounts",
})) as string[] | undefined;
if (!accounts || accounts.length === 0) {
throw new Error("No MetaMask accounts connected");
}
const connected = accounts.find(
(acc) => acc.toLowerCase() === owner.toLowerCase(),
);
if (!connected) {
throw new Error(
`MetaMask is not connected with the requested owner: ${owner}`,
);
}
// Encode message as hex string
const msgHex = `0x${uint8ArrayToHex(value)}`;
try {
const signature = (await window.ethereum.request({
method: "personal_sign",
params: [msgHex, owner],
})) as string;View on GitHub (pinned to 6c226ddcb3)
Solutions
- Verify you are operating on the right chain: print chain_info() and check manager.ownership before calling share_ownership.
- For an ownerless child chain, complete the assignment from the parent (assign_new_chain_to_key) so it becomes active, then share ownership.
- If all owners were removed by mistake, the chain can only be recovered through governance/admin procedures — file/consult the Linera team; do not retry share_ownership.
- In application code, gate ownership operations on an is_active() pre-check and surface a clear message.
Example fix
// before: sharing ownership on an ownerless chain
client.share_ownership(new_owner, 100).await?; // InactiveChain
// after: check ownership first and assign from the parent if inactive
let ownership = client.chain_info().await?.manager.ownership;
if !ownership.is_active() {
parent.assign_new_chain_to_key(owner, description).await?;
}
client.share_ownership(new_owner, 100).await?; Defensive patterns
Strategy: validation
Validate before calling
// Guard ownership mutations with an activity check
let ownership = client.prepare_chain().await?.manager.ownership.clone();
if !ownership.is_active() {
return Err(anyhow::anyhow!("cannot share ownership: chain {} is inactive", client.chain_id()));
} Type guard
pub async fn chain_is_active_for_ownership(client: &ChainClient) -> Result<bool, Error> {
Ok(client.chain_info().await?.manager.ownership.is_active())
} Try / catch
match client.share_ownership(new_owner, weight).await {
Ok(outcome) => outcome,
Err(Error::ChainError(ChainError::InactiveChain(chain_id))) => {
// wrong chain or ownerless chain: assign an owner from the parent, or stop
return Err(anyhow::anyhow!("chain {chain_id} has no owners; complete owner assignment first"));
}
Err(e) => return Err(e),
} Prevention
- Double-check the chain id in wallet/config before ownership operations.
- Complete assign_new_chain_to_key for new child chains before rotating or sharing ownership.
- Surface ownership state in ops dashboards so ownerless chains are visible.
- Treat ownerless-but-funded chains as requiring governance recovery; do not script retries.
When it happens
Trigger: Calling share_ownership on a chain where manager.ownership is inactive (no regular and no super owners). Producers: chains created but never assigned an owner; chains where all owner weights were set to 0; using a client bound to the wrong chain id.
Common situations: Misconfigured CHAIN_ID / wallet pointing at an ownerless chain; child chains not yet assigned from the parent; automated setups that try to rotate keys on a chain that lost its owners.
Related errors
- Invalid owner address
- no signer found for owner ${owner}
- Invalid owner address
- MetaMask is not available
- MetaMask is not connected with the requested owner: ${owner}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/bb673ad721439873.
Report an issue: GitHub.