DocsReference

Errors

The twenty errors the curta program returns: each code and name, what it means, and what raises it in each instruction.

Codes

The curta program returns its errors as custom program errors. The codes run from 6000 to 6019, in the order the program declares them.

CodeErrorWhat it means
6000InvalidInstructionThe instruction data does not decode: an unknown tag, a wrong length, an empty weight chunk, a fund amount of zero, or a weight account count other than 1 or 2.
6001InvalidAccountThe account list is wrong: its length, an account that is not at the address the program derives or records, a wrong type tag, a wrong writable flag, or one account passed in two roles.
6002MissingSignatureAn account that must sign did not sign.
6003InvalidOwnerAn account is not owned by the curta program.
6004InvalidSizeAn account’s data length, or a weight chunk’s length, is not the one the instruction requires.
6005AlreadyInitializedAn account that must be new already holds data.
6006InvalidAuthorityThe signer is not the key the account records: the Config authority, the model’s publisher or the run’s opener. For init_config, the signer is not the program’s upgrade authority.
6007InvalidStateThe model or run is not in the state the instruction needs.
6008InvalidConfigA value is outside its range: the turn reward, the protocol share rate, the model’s configuration, the prompt length or max tokens.
6009InvalidModelThe model’s name is invalid, the model or Config passed is not the one the run records, or a turn names an unsealed model.
6010InvalidWeightsA weight account, a section or its contents does not match the model.
6011InvalidOffsetA write offset is not a multiple of 800, or a seal step is not the model’s current step.
6012HashMismatchThe hash of the written weights differs from the weights hash the model declared.
6013ArithmeticOverflowA lamport or counter sum passes 64 bits.
6014InsufficientBudgetA turn’s charge is above the run’s budget remaining.
6015StaleTurnA turn names a turn index the run has passed: another turn landed first.
6016CoreErrorThe inference core returned an error.
6017NotSettledclose_run was sent for a run that has not settled.
6018InvalidEventThe event authority account is not the program’s, or an event instruction is malformed.
6019InsufficientFundsAn account holds fewer lamports than the instruction needs.

The sections below give the exact condition behind each error, instruction by instruction. An error from the inference core reaches a client as CoreError: the program translates every core failure to that one code.

Reading an error

A failed transaction reports the error as a custom code on the instruction that raised it. @curta/sdk exports the names as PROGRAM_ERRORS, and decodeProgramError(code) turns a code into its name, or null for a code outside the program’s range.

error.ts
import { decodeProgramError } from '@curta/sdk'

const status = (await connection.getSignatureStatuses([signature])).value[0]
const err = status?.err as { InstructionError?: [number, { Custom?: number }] } | null

const custom = err?.InstructionError?.[1]?.Custom
if (custom !== undefined) console.log(decodeProgramError(custom))   // 'StaleTurn' for 6015

client.send throws when a transaction fails, with the signature and the error as JSON in the message. A program that calls Curta by CPI sees the same numeric code, since the code belongs to the first program that failed. On the site, a rejected transaction shows its reason at the action that sent it.

Every instruction

These checks come first on every instruction, whatever its tag.

CodeErrorRaised when
6000InvalidInstructionThe data is empty, or its first byte is not a tag from 0 to 12.
6000InvalidInstructionThe arguments are shorter than the instruction’s layout, or bytes remain after the last argument.
6001InvalidAccountThe program id of the instruction is not the curta program.
6001InvalidAccountThe account list is not exactly the instruction’s own accounts plus the two trailing ones, or the last account is not the executable curta program.
6001InvalidAccountAn account the instruction writes is not marked writable.
6002MissingSignatureAn account the instruction requires as signer did not sign.
6018InvalidEventThe account before the last is not the event authority address.

Each Config, Model, Run, weight or vault account an instruction takes passes these:

CodeErrorRaised when
6001InvalidAccountThe account’s first eight bytes are not its type’s tag, or a Config account is not at the address derived from "config".
6003InvalidOwnerA Config, Model, Run, weight or vault account is not owned by the curta program.
6004InvalidSizeThe account’s data is shorter than its type: 128 bytes for Config, 4,096 for Model, 256 for Run, 8 for a vault. A weight account is not exactly 2,048 bytes plus its section’s length.

Config instructions

init_config and set_config.

CodeErrorInstructionRaised when
6001InvalidAccountinit_configconfig or feeVault is not the address its seeds and the bump passed derive.
6001InvalidAccountinit_configsystemProgram is not the System program.
6005AlreadyInitializedinit_configconfig or feeVault already holds data or is owned by a program other than System.
6006InvalidAuthorityinit_configprogramData is not owned by the upgradeable loader, is not a ProgramData account, or names an upgrade authority other than the signer.
6006InvalidAuthorityinit_configThe curta program account does not point at the programData account passed.
6006InvalidAuthorityset_configThe signer is not the authority the Config records.
6008InvalidConfiginit_configThe turn reward is zero, or the protocol share is above 10,000 basis points.
6008InvalidConfigset_configThe turn reward is zero, or the protocol share is above 10,000 basis points.

Model instructions

create_model, write_weights, seal_model, set_royalty and claim_royalties.

CodeErrorInstructionRaised when
6000InvalidInstructionwrite_weightsThe chunk is empty.
6001InvalidAccountcreate_modelmodelVault is not the address derived for this model, or systemProgram is not the System program.
6001InvalidAccountclaim_royaltiespublisher and modelVault are the same account.
6003InvalidOwnercreate_modelmodel is not owned by the curta program.
6003InvalidOwnerwrite_weightsweights is not owned by the curta program.
6003InvalidOwnerseal_modelweights is not owned by the curta program.
6004InvalidSizecreate_modelmodel is not exactly 4,096 bytes.
6004InvalidSizewrite_weightsThe chunk runs past the section’s end, or its length is not the smaller of 800 and the bytes left from the offset.
6004InvalidSizewrite_weightsweights is not exactly 2,048 bytes plus the section’s length.
6004InvalidSizeseal_modelweights is not exactly 2,048 bytes plus the section’s length.
6005AlreadyInitializedcreate_modelmodel’s first 256 bytes are not all zero, or modelVault already holds data.
6005AlreadyInitializedwrite_weightsThe section has no bytes written and the weight account’s 2,048-byte header is not all zero.
6006InvalidAuthoritywrite_weightsThe signer is not the model’s publisher.
6006InvalidAuthorityseal_modelThe signer is not the model’s publisher.
6006InvalidAuthorityset_royaltyThe signer is not the model’s publisher.
6006InvalidAuthorityclaim_royaltiesThe signer is not the model’s publisher, or modelVault is not the vault the model records.
6007InvalidStatewrite_weightsThe model is sealed, or sealing has begun.
6007InvalidStateseal_modelThe model is already sealed.
6008InvalidConfigcreate_modelThe configuration is outside the supported ranges.
6009InvalidModelcreate_modelThe name is empty, longer than 64 bytes, or not UTF-8.
6010InvalidWeightscreate_modelThe section count is below 2 or above 64, a section length is zero or above 10,483,712 bytes, or two sections name the same address.
6010InvalidWeightswrite_weightsThe section index is not below the model’s section count, or weights is not the address the model names for that section.
6010InvalidWeightswrite_weightsThe section has bytes written and the weight account’s header does not carry this model and section.
6010InvalidWeightswrite_weightsThe chunk’s bit is set and the bytes differ from the ones stored, or the bit is clear and the target bytes are not all zero.
6010InvalidWeightsseal_modelA section’s bytes written differ from its length.
6010InvalidWeightsseal_modelweights is not the address the model names for the section being sealed, or its header does not carry this model and section.
6010InvalidWeightsseal_modelOn section zero: the metadata does not parse, its structure is invalid, its configuration, section count or section lengths differ from the Model’s, or a tokenizer entry in this step’s 512 is invalid.
6011InvalidOffsetwrite_weightsThe offset is not a multiple of 800.
6011InvalidOffsetseal_modelexpectedStep is not the model’s seal step.
6012HashMismatchseal_modelThe step finishes the last section and the running hash differs from the weights hash.
6013ArithmeticOverflowcreate_modelThe section lengths sum past 64 bits.
6013ArithmeticOverflowseal_modelThe seal step passes 64 bits.
6019InsufficientFundscreate_modelmodel holds fewer lamports than the rent of 4,096 bytes.
6019InsufficientFundsclaim_royaltiesThe amount is above the vault’s balance less the rent of 8 bytes.

Run instructions

open_run, turn, fund, cancel, settle and close_run.

CodeErrorInstructionRaised when
6000InvalidInstructionturnweightAccountCount is not 1 or 2.
6000InvalidInstructionfundThe amount is zero.
6001InvalidAccountopen_runsystemProgram is not the System program, or run and opener are the same account.
6001InvalidAccountturncranker and run are the same account, or model, config or a weight account is marked writable.
6001InvalidAccountfundsystemProgram is not the System program, or funder and run are the same account.
6001InvalidAccountsettlemodelVault is not the vault the model records, or feeVault is not the one the Config records.
6001InvalidAccountclose_runopener and run are the same account.
6003InvalidOwneropen_runrun is not owned by the curta program.
6003InvalidOwnerturnA weight account is not owned by the curta program.
6004InvalidSizeopen_runrun is not exactly 256 bytes plus the working state for this prompt length and maxTokens.
6004InvalidSizeturnThe run account’s length is not 256 bytes plus the working state length it records.
6005AlreadyInitializedopen_runrun’s first 256 bytes are not all zero.
6006InvalidAuthoritycancelThe signer is not the run’s opener.
6006InvalidAuthorityclose_runThe signer is not the run’s opener.
6007InvalidStateopen_runThe model is not sealed.
6007InvalidStateturnThe run is not running.
6007InvalidStatefundThe run is complete or cancelled.
6007InvalidStatecancelThe run is complete or already cancelled.
6007InvalidStatesettleThe run is running or starved, or is already settled.
6008InvalidConfigopen_runThe prompt is longer than 1,024 bytes, or maxTokens is zero or above the model’s context length.
6009InvalidModelturnmodel or config is not the one the run records, or the model is not sealed.
6009InvalidModelsettlemodel or config is not the one the run records.
6010InvalidWeightsopen_runmetadata is not the model’s section zero account, its header does not carry this model, or its configuration differs from the Model’s.
6010InvalidWeightsturnweightAccountCount differs from the number of matrix sections this turn reads, or a weight account is not the one the model names for the section the turn reads at that position.
6013ArithmeticOverflowopen_runRent plus budget, or the model’s run counter, passes 64 bits.
6013ArithmeticOverflowturnA reward, royalty or protocol share sum passes 64 bits.
6013ArithmeticOverflowfundThe budget deposited or remaining passes 64 bits.
6013ArithmeticOverflowsettleThe model’s token or royalty counter passes 64 bits.
6014InsufficientBudgetturnThe turn’s charge is above the budget remaining.
6015StaleTurnturnexpectedTurn is not the run’s turn count: another turn landed first.
6016CoreErroropen_runThe prompt contains a zero byte or is not UTF-8, or the temperature is above 1,048,576.
6016CoreErrorturnThe inference core returns an error while planning or computing the turn.
6017NotSettledclose_runThe run’s settled flag is clear.
6019InsufficientFundsopen_runrun holds fewer lamports than its rent plus the budget.
6019InsufficientFundssettleThe run account holds fewer lamports than the amounts owed.

StaleTurn and a starved run

Two outcomes of a turn are part of ordinary operation. StaleTurn means another cranker landed that turn index first: read the run again and send the next index. A turn that finds the budget below its reserve succeeds without an error, sets the run to starved and pays no reward; a turn sent to a starved run then raises InvalidState until a fund returns it to running. Run a cranker shows how the cranker treats both.

The event instruction

The program emits each event as a call to itself whose data opens with the 8-byte event tag. That call is checked like any other:

CodeErrorRaised when
6002MissingSignatureThe event authority did not sign. Only the program signs for it, so an event instruction sent from outside the program raises this.
6018InvalidEventThe data after the 8-byte event tag is shorter than 149 bytes, or its token list is not a whole number of 4-byte ids.
6018InvalidEventThe instruction carries more or fewer than one account, or that account is not the event authority address.