Events & Error Codes

March 11, 2026 · View on GitHub

Synapse Agent Protocol (SAP) v2 ... 45 Events, 91 Errors
Program ID: SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ
Anchor 0.32.1 · Solana SVM

All SAP state mutations emit structured Anchor events to the transaction log. These events are permanent, zero-rent, and form the backbone of the protocol's auditability and data indexing layer. This document catalogues every event and error the program can produce.


Table of Contents

Events

  1. Agent Events (7)
  2. Feedback Events (3)
  3. Vault Events (11)
  4. Tool Events (8)
  5. Escrow Events (5)
  6. Attestation Events (2)
  7. Memory Events (9)

Errors 8. Error Codes (91)


Events

Anchor events are emitted via emit!() and serialized into the transaction's log data. Parse them with program.addEventListener("EventName", callback) in the TypeScript client, or decode from raw transaction logs using program.coder.events.decode().


Agent Events

7 events covering the full agent lifecycle.

EventKey FieldsEmitted By
RegisteredEventagent, wallet, name, capabilities[], timestampregister_agent
UpdatedEventagent, wallet, updated_fields[], timestampupdate_agent
DeactivatedEventagent, wallet, timestampdeactivate_agent
ReactivatedEventagent, wallet, timestampreactivate_agent
ClosedEventagent, wallet, timestampclose_agent
CallsReportedEventagent, wallet, calls_reported, total_calls_served, timestampreport_calls
ReputationUpdatedEventagent, wallet, avg_latency_ms, uptime_percent, timestampupdate_reputation

UpdatedEvent.updated_fields: Strings listing which fields were changed (e.g., ["name", "pricing", "x402_endpoint"]). Useful for incremental indexers that need to know what changed without diffing the full account.


Feedback Events

3 events for the trustless reputation system.

EventKey FieldsEmitted By
FeedbackEventagent, reviewer, score, tag, timestampgive_feedback
FeedbackUpdatedEventagent, reviewer, old_score, new_score, timestampupdate_feedback
FeedbackRevokedEventagent, reviewer, timestamprevoke_feedback

Note: FeedbackUpdatedEvent carries both old_score and new_score, making it possible to reconstruct reputation history without fetching account state at every point.


Vault Events

11 events covering vault lifecycle, sessions, inscriptions, delegation, and nonce rotation.

EventKey FieldsEmitted By
VaultInitializedEventagent, vault, wallet, timestampinit_vault
SessionOpenedEventvault, session, session_hash, timestampopen_session
MemoryInscribedEventvault, session, sequence, epoch_index, encrypted_data, nonce, content_hash, total_fragments, fragment_index, compression, data_len, nonce_version, timestampinscribe_memory, inscribe_memory_delegated, compact_inscribe
EpochOpenedEventsession, epoch_page, epoch_index, start_sequence, timestampinscribe_memory (auto, on epoch boundary)
SessionClosedEventvault, session, total_inscriptions, total_bytes, total_epochs, timestampclose_session
VaultClosedEventvault, agent, wallet, total_sessions, total_inscriptions, timestampclose_vault
SessionPdaClosedEventvault, session, total_inscriptions, total_bytes, timestampclose_session_pda
EpochPageClosedEventsession, epoch_page, epoch_index, timestampclose_epoch_page
VaultNonceRotatedEventvault, wallet, old_nonce, new_nonce, nonce_version, timestamprotate_vault_nonce
DelegateAddedEventvault, delegate, permissions, expires_at, timestampadd_vault_delegate
DelegateRevokedEventvault, delegate, timestamprevoke_vault_delegate

MemoryInscribedEvent is the core data carrier. The encrypted_data field contains AES-256-GCM ciphertext. The nonce (12 bytes) and nonce_version are required for decryption. compression values: 0=none, 1=deflate, 2=gzip, 3=brotli.

VaultNonceRotatedEvent emits the old_nonce so clients can still derive keys for historical inscriptions written before the rotation.


Tool Events

8 events for the onchain tool schema registry and session checkpoints.

EventKey FieldsEmitted By
ToolPublishedEventagent, tool, tool_name, protocol_hash, version, http_method, category, params_count, required_params, is_compound, timestamppublish_tool
ToolSchemaInscribedEventagent, tool, tool_name, schema_type, schema_data, schema_hash, compression, version, timestampinscribe_tool_schema
ToolUpdatedEventagent, tool, tool_name, old_version, new_version, timestampupdate_tool
ToolDeactivatedEventagent, tool, tool_name, timestampdeactivate_tool
ToolReactivatedEventagent, tool, tool_name, timestampreactivate_tool
ToolClosedEventagent, tool, tool_name, total_invocations, timestampclose_tool
ToolInvocationReportedEventagent, tool, invocations_reported, total_invocations, timestampreport_tool_invocations
CheckpointCreatedEventsession, checkpoint, checkpoint_index, merkle_root, sequence_at, epoch_at, timestampcreate_session_checkpoint

ToolSchemaInscribedEvent is the schema data carrier. schema_type: 0=input, 1=output, 2=description. Verification: sha256(schema_data) == schema_hash. compression: 0=none, 1=deflate.


Escrow Events

5 events for x402 micropayment settlement.

EventKey FieldsEmitted By
EscrowCreatedEventescrow, agent, depositor, price_per_call, max_calls, initial_deposit, expires_at, timestampcreate_escrow
EscrowDepositedEventescrow, depositor, amount, new_balance, timestampdeposit_escrow
PaymentSettledEventescrow, agent, depositor, calls_settled, amount, service_hash, total_calls_settled, remaining_balance, timestampsettle_calls
EscrowWithdrawnEventescrow, depositor, amount, remaining_balance, timestampwithdraw_escrow
BatchSettledEventescrow, agent, depositor, num_settlements, total_calls, total_amount, service_hashes[], calls_per_settlement[], remaining_balance, timestampsettle_batch

PaymentSettledEvent serves as a permanent, zero-rent receipt. The service_hash is a SHA-256 proof of service ... the agent computes it over the work performed, enabling dispute resolution by third parties.

BatchSettledEvent preserves individual service_hashes and calls_per_settlement for granular auditability even when multiple settlements are batched.


Attestation Events

2 events for the web-of-trust system.

EventKey FieldsEmitted By
AttestationCreatedEventagent, attester, attestation_type, expires_at, timestampcreate_attestation
AttestationRevokedEventagent, attester, attestation_type, timestamprevoke_attestation

Memory Events

9 events across legacy memory systems and the recommended Memory Ledger.

Legacy Memory (gated behind legacy-memory feature)

EventKey FieldsEmitted By
MemoryStoredEventagent, entry_hash, content_type, timestampstore_memory
BufferCreatedEventsession, buffer, authority, page_index, timestampcreate_buffer
BufferAppendedEventsession, buffer, page_index, chunk_size, total_size, num_entries, timestampappend_buffer
DigestPostedEventsession, digest, content_hash, data_size, entry_index, merkle_root, timestamppost_digest
DigestInscribedEventsession, digest, entry_index, data, content_hash, data_len, merkle_root, timestampinscribe_to_digest
StorageRefUpdatedEventsession, digest, storage_ref, storage_type, timestampupdate_digest_storage
EventKey FieldsEmitted By
LedgerEntryEventsession, ledger, entry_index, data, content_hash, data_len, merkle_root, timestampwrite_ledger
LedgerSealedEventsession, ledger, page, page_index, entries_in_page, data_size, merkle_root_at_seal, timestampseal_ledger

LedgerEntryEvent carries the raw data in the data field ... this is the permanent TX log record. The merkle_root is the rolling accumulator after this write, enabling tamper-proof chain verification.

LedgerSealedEvent records the merkle_root_at_seal, letting any verifier confirm that a LedgerPage PDA's contents match the merkle state at seal time.


Error Codes

All 91 error codes are defined in the SapError enum. Anchor assigns auto-incremented error codes starting at 6000. The tables below organize errors by domain.

Agent Validation (10 errors)

CodeErrorMessageTrigger
6000NameTooLongname>64Agent name exceeds 64 bytes
6001DescriptionTooLongdesc>256Description exceeds 256 bytes
6002UriTooLonguri>256URI exceeds 256 bytes
6003TooManyCapabilitiescaps>10More than 10 capabilities
6004TooManyPricingTierstiers>5More than 5 pricing tiers
6005TooManyProtocolsprotos>5More than 5 protocols
6006TooManyPluginsplugins>5More than 5 plugins
6007AlreadyActivealready activeAgent is already active
6008AlreadyInactivealready inactiveAgent is already inactive
6035AgentInactiveagent inactiveOperation requires active agent

Deep Validation (15 errors)

CodeErrorMessageTrigger
6017EmptyNameempty nameName is zero-length
6018ControlCharInNamectrl charName contains bytes < 0x20
6019EmptyDescriptionempty descDescription is zero-length
6020AgentIdTooLongagentid>128Agent ID exceeds 128 bytes
6021InvalidCapabilityFormatcap formatCapability not in domain:action format
6022DuplicateCapabilitydup capDuplicate capability ID
6023EmptyTierIdempty tierPricing tier ID is empty
6024DuplicateTierIddup tierDuplicate pricing tier ID
6025InvalidRateLimitrate=0Rate limit is zero
6026SplRequiresTokenMintspl needs mintSPL token type without token_mint
6027InvalidX402Endpointx402 httpsx402 endpoint doesn't start with https://
6028InvalidVolumeCurvecurve orderVolume curve after_calls not strictly ascending
6029TooManyVolumeCurvePointscurve>5More than 5 volume curve breakpoints
6030MinPriceExceedsMaxmin>max pricemin_price_per_call > max_price_per_call
6031InvalidUptimePercentuptime 0-100Uptime percent > 100

Feedback (5 errors)

CodeErrorMessageTrigger
6009InvalidFeedbackScorescore 0-1000Score outside 0...1000 range
6010TagTooLongtag>32Tag exceeds 32 bytes
6011SelfReviewNotAllowedself reviewReviewer wallet == agent owner wallet
6012FeedbackAlreadyRevokedalready revokedFeedback is already revoked
6047FeedbackNotRevokednot revokedAttempting to close non-revoked feedback

Indexing (4 errors)

CodeErrorMessageTrigger
6013CapabilityIndexFullcap idx fullCapability index has 100 agents
6014ProtocolIndexFullproto idx fullProtocol index has 100 agents
6015AgentNotInIndexnot in idxAttempting to remove absent agent
6048IndexNotEmptyidx not emptyAttempting to close non-empty index

Vault (9 errors)

CodeErrorMessageTrigger
6032SessionClosedsession closedWriting to a closed session
6033InvalidSequencebad seqSequence doesn't match session.sequence_counter
6034InvalidFragmentIndexfrag idxfragment_index >= total_fragments
6037InscriptionTooLargedata>750Encrypted data exceeds 750 bytes
6038EmptyInscriptionempty dataZero-length inscription data
6039InvalidTotalFragmentsfrags<1total_fragments < 1
6040EpochMismatchepoch mismatchepoch_index != session.current_epoch
6041VaultNotClosedvault openVault has open sessions when closing
6042SessionNotClosedsession openSession is still open when closing PDA

Delegation (2 errors)

CodeErrorMessageTrigger
6043DelegateExpireddelegate expiredDelegate's expires_at has passed
6044InvalidDelegatebad delegateDelegate lacks required permission bit

Tools (10 errors)

CodeErrorMessageTrigger
6045ToolNameTooLongtool>32Tool name exceeds 32 bytes
6046EmptyToolNameempty toolTool name is zero-length
6049InvalidToolNameHashtool hashsha256(tool_name) != tool_name_hash
6050InvalidToolHttpMethodbad methodHTTP method not in 0...4 range
6051InvalidToolCategorybad categoryCategory not in 0...9 range
6052ToolAlreadyInactivetool inactiveTool is already inactive
6053ToolAlreadyActivetool activeTool is already active
6054InvalidSchemaHashschema hashSchema hash verification failed
6055InvalidSchemaTypeschema typeschema_type not in 0...2
6056InvalidCheckpointIndexcp indexcheckpoint_index != session.total_checkpoints

Escrow (6 errors)

CodeErrorMessageTrigger
6058InsufficientEscrowBalancelow balanceBalance can't cover settlement amount
6059EscrowMaxCallsExceededmax callsWould exceed max_calls limit
6060EscrowEmptyescrow emptyWithdrawal from zero-balance escrow
6061EscrowNotEmptyescrow!=0Closing escrow with remaining balance
6062InvalidSettlementCallscalls<1calls_to_settle is zero
6036EscrowExpiredescrow expiredEscrow has passed expires_at

Attestation (6 errors)

CodeErrorMessageTrigger
6063AttestationTypeTooLongatype>32Attestation type exceeds 32 bytes
6064EmptyAttestationTypeempty atypeAttestation type is zero-length
6065SelfAttestationNotAllowedself attestAttester wallet == agent owner wallet
6066AttestationAlreadyRevokedalready revokedAttestation is already revoked
6067AttestationNotRevokednot revokedClosing non-revoked attestation
6069AttestationExpiredattest expiredAttestation has passed expires_at

Memory (9 errors)

CodeErrorMessageTrigger
6016ChunkDataTooLargechunk>900Legacy memory chunk exceeds 900 bytes
6070ContentTypeTooLongctype>maxContent type string too long
6071IpfsCidTooLongcid>maxIPFS CID string too long
6072BufferFullbuf fullBuffer would exceed 10 KB max
6073BufferDataTooLargebuf>750Single buffer append exceeds 750 bytes
6074UnauthorizedunauthorizedSigner is not the session authority
6075InvalidSessionbad sessionSession PDA is invalid or mismatched
6076EmptyDigestHashempty hashContent hash is all zeros
6077LedgerDataTooLargeledger>750Ledger write data exceeds 750 bytes

Tool Category Index (3 errors)

CodeErrorMessageTrigger
6068ToolCategoryIndexFullcat idx fullCategory index has 100 tools
6079ToolNotInCategoryIndexnot in catTool not found in category index
6080ToolCategoryMismatchcat mismatchTool's category doesn't match index

Batch (2 errors)

CodeErrorMessageTrigger
6081BatchEmptybatch emptySettlements vector is empty
6082BatchTooLargebatch>10More than 10 settlements in batch

SPL Token (3 errors)

CodeErrorMessageTrigger
6083SplTokenRequiredspl acctsSPL escrow missing token accounts
6084InvalidTokenAccountbad tokenToken account doesn't match expected mint/owner
6085InvalidTokenProgrambad progWrong token program passed

Safety (4 errors)

CodeErrorMessageTrigger
6034ArithmeticOverflowoverflowInteger overflow in counter arithmetic
6057NoFieldsToUpdateno fieldsupdate_agent / update_tool called with all None
6049SessionStillOpensession openAttempting to close PDA while session is open
6078LedgerRingEmptyring emptyAttempting to seal an empty ring buffer

Note on error codes: Anchor assigns error codes sequentially starting at 6000 per the enum declaration order. The codes listed above are derived directly from the SapError enum position. Some sharing of numeric codes between logical groups reflects that the same underlying error serves multiple contexts (e.g., InvalidPluginType at 6016 is used by both plugin and memory domains).


Event Parsing Example

// Listen for real-time events
const listenerId = program.addEventListener("PaymentSettledEvent", (event, slot) => {
  console.log(`Settlement: ${event.callsSettled} calls, ${event.amount} lamports`);
  console.log(`Service hash: ${Buffer.from(event.serviceHash).toString("hex")}`);
  console.log(`Remaining: ${event.remainingBalance} lamports`);
});

// Parse from transaction logs
const tx = await connection.getTransaction(signature, { maxSupportedTransactionVersion: 0 });
const events = program.coder.events.decode(tx.meta.logMessages);

Error Handling Example

import { AnchorError } from "@coral-xyz/anchor";

try {
  await program.methods.registerAgent(/* ... */).rpc();
} catch (err) {
  if (err instanceof AnchorError) {
    switch (err.error.errorCode.code) {
      case "EmptyName":
        console.error("Agent name cannot be empty");
        break;
      case "InvalidCapabilityFormat":
        console.error("Capabilities must be in 'domain:action' format");
        break;
      case "DuplicateTierId":
        console.error("Pricing tier IDs must be unique");
        break;
      default:
        console.error(`SAP error: ${err.error.errorMessage}`);
    }
  }
}

Previous: 03-accounts.md · Next: 05-architecture.md