linera-io/linera-protocol · warning · async_graphql::Error
You must claim a chain before making daily claims
Error message
You must claim a chain before making daily claims
What it means
`dailyClaim` requires a completed initial claim: the faucet looks up `initial_claim(&owner)` in its database and refuses with DAILY_NO_CHAIN_MSG when no record exists. The owner is the AccountOwner key used in the original `claim` — the daily transfer goes to the chain created by that first claim. Calling `dailyClaim` with a fresh owner, or before `claim` has returned, produces this error.
Source
Thrown at linera-faucet/server/src/lib.rs:572
// under its own `result` label: these paths return before the queue round-trip
// that increments `CLAIM_REQUESTS_TOTAL`, so without the explicit counters
// refusals are invisible in metrics (they only appear as unlabelled
// `claim_latency_ms{result="error"}` observations).
if self.daily_claim_amount == Amount::ZERO {
#[cfg(with_metrics)]
metrics::CLAIM_REQUESTS_TOTAL
.with_label_values(&["daily_disabled"])
.inc();
return Err(Error::new(DAILY_DISABLED_MSG));
}
// The user must have done the initial claim first.
let Some(initial_claim) = self.faucet_storage.initial_claim(&owner).await? else {
#[cfg(with_metrics)]
metrics::CLAIM_REQUESTS_TOTAL
.with_label_values(&["daily_no_chain"])
.inc();
return Err(Error::new(DAILY_NO_CHAIN_MSG));
};
let now = self.storage.clock().current_time();
let period = current_daily_period(initial_claim.timestamp.micros(), now.micros());
let last_period = self
.faucet_storage
.last_daily_claim_period(&owner)
.await?
.unwrap_or(0);
if period <= last_period {
#[cfg(with_metrics)]
metrics::CLAIM_REQUESTS_TOTAL
.with_label_values(&["daily_limit"])
.inc();
return Err(Error::new(DAILY_LIMIT_MSG));
}
View on GitHub (pinned to 6c226ddcb3)
Solutions
- Call `claim(owner)` first and wait for its ChainDescription, then use the same owner for `dailyClaim`
- Persist the owner key (wallet file) so the initial claim is reused instead of creating a new identity per run
- If the faucet DB was reset but you still hold the chain, re-run `claim` — the duplicate path returns the existing chain description from storage
- Before retrying, verify the record exists with the `initialClaim(owner)` or `chainId(owner)` GraphQL queries
Example fix
// before - daily claim with an owner that never claimed let outcome = client.daily_claim(new_owner, None).await?; // Err: You must claim a chain before making daily claims // after - complete the initial claim first, then reuse the same owner let description = client.claim(owner, None).await?; let outcome = client.daily_claim(owner, None).await?;
Defensive patterns
Strategy: validation
Validate before calling
// Run before dailyClaim - the faucet exposes these queries:
// query { initialClaim(owner: "<AccountOwner>") { chainId timestamp } }
// -> null means no initial claim: call `claim` first.
// query { chainId(owner: "<AccountOwner>") }
// -> errors with `This user has no chain yet` when nothing is registered. Type guard
fn needs_initial_claim(msg: &str) -> bool { msg == "You must claim a chain before making daily claims" } Try / catch
Catch the `dailyClaim` error; on `You must claim a chain before making daily claims`, run `claim(owner)` with the SAME owner, wait for the ChainDescription, then retry `dailyClaim` once.
Prevention
- Always run `claim(owner)` to completion before the first `dailyClaim` for that owner
- Persist the owner key/wallet so the initial claim is reused across sessions instead of generating a new identity
- Use one owner identity per user; do not mint fresh AccountOwners for daily claims
When it happens
Trigger: Calling `dailyClaim(owner)` where that exact AccountOwner never completed a `claim`; generating a new key/wallet per session and using it for daily claims; the faucet's claim database having been reset so the initial-claim record is gone even though the chain still exists on-chain.
Common situations: Example apps and bots that regenerate a keypair on every run; a client firing `dailyClaim` before the initial claim's ChainDescription came back; faucet database wiped/recreated during maintenance so owner→chain mappings were lost.
Related errors
- Daily claims are not enabled on this faucet
- You have already claimed tokens for this period
- InvalidCrossChainRequest
- UnexpectedBlockHeight
- InvalidBlockChaining
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/37a354d251f3b3db.
Report an issue: GitHub.