Skip to content

Technical Reference: Error Code Taxonomy

Metadata Specification
Document ID TP-REFR-004
Category Exception Codes & Failure Modes
Last updated April 2026

The TIMLG Protocol uses Anchor #[error_code] enums to signal failure conditions. The list below covers the errors users, operators, and reviewers encounter most often. The full enum lives in programs/timlg_protocol/src/errors.rs in the public code repository.

1. Lifecycle and timing

Error Code Description
CommitClosed Attempted to commit a ticket after commit_deadline_slot
CommitAfterPulseSet Commit rejected because the pulse for the round is already set
RevealPhaseNotOpen Attempted to reveal before the oracle pulse has been published
RevealClosed Attempted to reveal after reveal_deadline_slot
PulseNotSet Operation requires the round pulse to be set
PulseAlreadySet Pulse for the round is already set (idempotent retry by supervisors)
PulseTooLate Late pulse rejected because too few slots remain before reveal expiry
SweepTooEarly Sweep attempted before claim_grace_slots elapsed
AlreadySwept Sweep already executed for the round
ClaimAfterSweep Cannot claim a reward once the round is swept
RoundNotSettled Operation requires settle_round_tokens to have run
SettleTooEarly Settlement attempted before reveal window closed
RoundTokensAlreadySettled Token settlement already complete for the round
RefundTooEarly Refund path is not yet open (no pulse and REFUND_TIMEOUT_SLOTS not elapsed)
ClaimWindowClosed Claim window expired
ContinuityRoundNoCommit Continuity-kind rounds reject commits and reveals

2. Commit / reveal correctness

Error Code Description
InvalidCommitment / CommitmentMismatch Reveal (guess, salt) does not hash to the on-chain commitment
InvalidGuess Guess byte must be 0 or 1
BitIndexMismatch The bit index recorded at commit does not match the recomputed value
AlreadyRevealed Ticket has already been revealed
TooManyEntries Batch instruction received more entries than MAX_BATCH
TicketAlreadyExists Commit attempted with a nonce already in use
StakeAlreadyPaid Ticket stake was already moved to the round vault
StakeNotPaid Ticket cannot proceed because stake was not escrowed

3. Oracle and quorum

Error Code Description
MissingOrInvalidEd25519Ix Transaction missing or has an invalid Ed25519 verify instruction
Ed25519PubkeyMismatch Signed pulse does not come from the expected oracle
Ed25519MessageMismatch The Ed25519 message bytes do not match the canonical envelope
OracleNotSet Single-signer oracle pubkey is not configured
LegacyModeDisabled Single-signer pulse path is disabled for betting rounds (use quorum)
QuorumRequired Operation requires a multi-oracle quorum signature set
QuorumBelowThreshold Fewer signatures than OracleSet.threshold
DuplicateQuorumSigner Two signatures came from the same oracle
QuorumSignerNotAllowed Signer is not in OracleSet
OracleSetFull / OracleNotFound / OracleAlreadyExists OracleSet management constraints
InvalidThreshold / ThresholdExceedsOracleCount Threshold value violates set size
InvalidQuorumSignatureOrdering Quorum signatures must be sorted by signer pubkey
MissingQuorumEd25519Instructions Quorum tx missing the required Ed25519 verify instructions
AnchorQuorumRequired Anchor recovery path requires the quorum variant
AllOracleSignaturesRequired Strict mode demands signatures from every authorized oracle

4. NIST chaining and pulse sequencing

Error Code Description
NistChainBroken New pulse's previous_output_value does not match Config.last_output_value
NistPrecommitmentBroken SHA-512(output_value) does not match Config.last_precommitment_value
PulseIndexMismatch Pulse pulse_index does not equal the round's pulse_index_target
NonSequentialPulse Pulse target is not exactly LFP + 1 (outside recovery)
PulseAlreadyPublished NIST pulse for this index was already accepted on-chain
NistAnchorMissing NIST anchor (latest_pulse_timestamp) is missing in Config

5. Round creation and registry

Error Code Description
NonCanonicalTarget requested_target is not max(last_created_target + 1, LFP + min_future_pulses)
ContinuityPrematureTarget Continuity fallback used too early (NIST has not published the target yet)
TargetAlreadyCreated A round for this pulse_index_target was already created
CommitTargetAlreadyKnown Cannot create a betting round for a pulse whose value is already known
PulseTooClose / PulseTooFar / PulseIndexNotFuture Target is outside the [min_future_pulses, max_future_pulses] window

6. Recovery mode

Error Code Description
RecoveryProofInvalid enter_recovery_mode requires a real pending Round at recovery_target
NoSequenceGap Recovery refused because there is no actual LFP gap
RecoveryNotActive Tried to install an anchor outside recovery mode
RecoveryAlreadyActive Recovery mode is already active — call exit_recovery_mode first
RecoveryWouldNotAdvance Anchor pulse_index does not advance LFP
RecoveryTargetMismatch Anchor pulse_index does not match Config.recovery_target_pulse
RecoveryExitNotJustified Permissionless exit refused: LFP has not reached the target and timeout has not elapsed
PulseIndexNotNext Outside recovery, anchor must target exactly LFP + 1

7. Streak Jackpot

Error Code Description
StreakDoesNotBeatRecord user_stats.current_streak <= leaderboard.record_streak — claim rejected
JackpotEmpty Treasury SOL has no lamports above the rent-exempt minimum
LeaderboardNotInitialized Admin has not yet called initialize_streak_leaderboard

8. Treasury and parameter caps

Error Code Description
StakeAmountTooHigh Stake exceeds MAX_STAKE_AMOUNT
CommitWindowTooLong / RevealWindowTooLong / OracleWindowTooLong Window exceeds the corresponding cap
FeeBpsTooHigh reward_fee_bps exceeds MAX_REWARD_FEE_BPS
TreasuryWithdrawBlocked Treasury withdrawal blocked by active rounds with unclaimed winners

9. Common environment / wallet errors

Error Code Description
Unauthorized Signer does not own the account it is acting on
Paused Protocol is paused
TIMLGMintMismatch Provided mint does not match Config.timlg_mint
InvalidUserTIMLGAta The user TIMLG token account is not derivable from the user's wallet
InsufficientFunds The user's wallet does not have enough TIMLG or SOL
MathOverflow Arithmetic overflow protected by checked_*

10. Reference

For the complete enum (all variants and discriminants), see:

programs/timlg_protocol/src/errors.rs