linera-io/linera-protocol · error · async_graphql::Error

This user has no chain yet

Error message

This user has no chain yet

What it means

The faucet server's chain_id GraphQL query looks up the chain the faucet created for a given AccountOwner; when the storage returns None it fails with this user-facing error. It means the faucet has no record of a claim by that owner — not that the chain doesn't exist on the network. Related queries like initial_claim hit storage the same way and only succeed for owners that already interacted with this faucet.

Source

Thrown at linera-faucet/server/src/lib.rs:370

    }

    /// Returns the current epoch of the faucet's chain.
    async fn current_epoch(&self) -> Result<Epoch, Error> {
        let info = self.client.chain_info().await?;
        Ok(info.epoch)
    }

    /// Find the existing chain with the given authentication key, if any.
    async fn chain_id(&self, owner: AccountOwner) -> Result<ChainId, Error> {
        // Check if this owner already has a chain.
        #[cfg(with_metrics)]
        let histogram = metrics::DATABASE_OPERATION_LATENCY.with_label_values(&["get_chain_id"]);
        #[cfg(with_metrics)]
        let _latency = histogram.measure_latency();

        let chain_id = self.faucet_storage.get_chain_id(&owner).await?;

        chain_id.ok_or_else(|| Error::new("This user has no chain yet"))
    }

    /// Returns the initial claim for the given owner, if any.
    async fn initial_claim(&self, owner: AccountOwner) -> Result<Option<InitialClaim>, Error> {
        let claim_record = self.faucet_storage.initial_claim(&owner).await?;

        Ok(claim_record.map(|r| InitialClaim {
            chain_id: r.chain_id,
            timestamp: r.timestamp,
        }))
    }

    /// Returns the earliest time at which the owner can make a daily claim.
    /// If the returned timestamp is in the past (or now), the user can claim immediately.
    /// Returns `None` if the user has not yet completed the initial claim.
    async fn next_daily_claim(&self, owner: AccountOwner) -> Result<Option<Timestamp>, Error> {
        let initial_claim = match self.faucet_storage.initial_claim(&owner).await? {
            Some(record) => record,

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Claim a chain from the faucet first: run the faucet's claim mutation (or the README example's faucet call) for that exact owner key, then re-query chain_id.
  2. Verify the owner value: recompute it from the same private key/derivation used at claim time and use its canonical formatting (0x-prefixed hex) in the query.
  3. If the faucet storage was wiped or you switched faucet instances, re-run the claim against the current faucet — records are per-faucet, not global.

Example fix

# before: querying before any claim
query { chainId(owner: "0xYOUR_OWNER") }   # -> "This user has no chain yet"

# after: claim once, then query
mutation { claim(owner: "0xYOUR_OWNER") { messageId } }
query { chainId(owner: "0xYOUR_OWNER") }   # returns the assigned chain
Defensive patterns

Strategy: fallback

Validate before calling

// No cheap pre-check exists server-side; probe by treating this error as the signal:
// (claim flow fills the role of validation — see tryCatchPattern)

Try / catch

match faucet_client.chain_id(owner).await {
    Ok(chain_id) => chain_id,
    Err(e) if e.message == "This user has no chain yet" => {
        // fall back: claim a chain for this owner, then retry once
        faucet_client.claim(owner).await?;
        faucet_client.chain_id(owner).await?
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Querying chain_id(owner: "0x…") against the faucet GraphQL endpoint for an owner that never claimed from this faucet (or whose claim used a different owner address), e.g. following the faucet example but skipping the claim step, or querying a fresh/dev faucet database.

Common situations: Running the faucet example scripts out of order (query before the claim mutation); pointing the client at a freshly restarted faucet whose storage was wiped; re-deriving the owner from a different key/derivation path so the address no longer matches the one used at claim time; reading someone else's chain from a faucet they never used.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/f38f66eabefbde5b. Report an issue: GitHub.