Skip to content

Error Codes

Every Tryll server response that is not a normal success reply carries an ErrorResponse frame with a numeric code and a human-readable message. Codes are grouped by the layer that produces them, and each range has a characteristic recovery strategy.

This page lists every code defined in ErrorCodes.h. A few are reserved or raised only by the client; their rows say so. If a client ever receives a code not listed here, treat it as a protocol violation (server/client version mismatch) and log both the code and the message verbatim.

Error-code ranges

Range Layer Typical recovery
1xxx Connection Reconnect after backoff; session state is gone.
2xxx Session Re-send CreateSessionRequest; stop issuing requests if the server is shutting down.
3xxx Agent Depends on the code. For a bad agent id, a graph that does not compile, or a storage path problem (3001–3003, 3008–3011), fix the graph or id and recreate the agent. Most other 3xxx codes leave the agent usable; see the per-code recovery.
4xxx Inference / workflow / voice input Local to the turn or request that failed; other turns and other agents are unaffected.
5xxx Protocol / framing Client bug or version mismatch; stop and investigate.
6xxx Model download User-actionable (disk, network, catalog); retry once resolved.
7xxx String storage Fix the input and re-create the storage.
8xxx Embedded string storage / mutable KB Fix the config, schema, or snapshot and retry.

The authoritative source of every code is tryll/common/include/tryll/ErrorCodes.h. Client libraries expose the same values: Tryll::Client::ErrorCode (C++), tryll_client.ErrorCode (Python), ETryllErrorCode (Unreal).


1xxx — Connection

These errors surface client-side only: the client failed to reach the server, lost the TCP connection, or timed out waiting for a reply. The server never emits 1xxx codes itself.

Code Name Meaning
1001 ConnectionFailed TCP connect to the configured host/port failed outright. The server process is not running or the port is blocked.
1002 ConnectionDropped The established connection was closed mid-session (peer close, socket error, network partition). Session state on the server is gone.
1003 Timeout The client gave up waiting for a response frame. The socket itself may still be healthy; typically the server is overloaded or a node hung.

Recovery: reconnect after exponential backoff; re-configure the session; recreate agents.


2xxx — Session

The server rejected a request because the session is not in the right state to accept it, or because the server is shutting down.

Code Name Meaning
2001 ServerShuttingDown The server is in graceful shutdown and no longer accepts new requests on this session. In-flight turns continue until they complete or time out.
2002 SessionNotReady The client issued a request (agent, model, storage, or voice) before sending CreateSessionRequest. CreateSession is mandatory and must come first.
2003 SessionAlreadyExists The client sent a second CreateSessionRequest on a connection that already has a session. CreateSession is one-shot.
2004 InvalidLocale CreateSessionRequest.locale is not a well-formed BCP-47 tag. Expected language[-script][-region] — e.g. de, pt-BR, zh-Hans-CN. The error message names what was wrong.
2005 InvalidEngineSet CreateSessionRequest.model_config carries an enum value outside its range (a role, engine, memory placement, or hotword-bias ordinal), or placement_hints names the same model twice. These are the only ways model_config fails: the engine list is advisory, so an empty, incomplete, or wrong list is not an error.

Recovery:

  • ServerShuttingDown — stop sending; close the socket; back off before attempting to reconnect.
  • SessionNotReady — send CreateSessionRequest first, then retry the original request.
  • SessionAlreadyExists — the session is already created; do not call CreateSession again. Reconnect if you need a fresh session with different model_config settings.
  • InvalidLocale — send a well-formed BCP-47 tag, or an empty one to clear the locale.
  • InvalidEngineSet — fix the out-of-range or duplicated model_config entry named in message and re-send CreateSessionRequest.

3xxx — Agent

The request targeted an agent that does not exist, the agent cannot be created because its graph is invalid, or the agent cannot accept the request in its current state. Dialog snapshot, locale-model and voice profile errors are also in this range.

Code Name Meaning
3001 InvalidAgentId The agent_id in the request does not match any agent the server knows about, including an agent that was already destroyed. Typically a client-side bookkeeping bug.
3002 AgentAlreadyDestroyed Defined but not currently returned. A request for a destroyed agent gets 3001.
3003 GraphCompilationFailed CreateAgentRequest carried a graph the server could not compile into an executable plan. The message field names the first validation failure (invalid start node, duplicate node names, missing model name, a malformed grammar on a Generate / GenerateAndSpeak node, etc.). Voice problems are not reported here: see 3023–3025.
3004 AgentBusy SendMessageRequest arrived while the agent's previous turn was still open — either running or paused. A paused turn stays open until it is resumed, cancelled, or times out. Also returned by ChangeAgentParam when a turn is running, by SetAgentVoice when a turn is running or paused, and by KV-cache operations that conflict with a running/paused turn or another cache operation.
3005 UnknownNode ChangeAgentParam named a node that does not exist in the agent's compiled graph.
3006 ParamNotMutable ChangeAgentParam targeted a parameter that cannot be changed at runtime (e.g., structural exit fields are fixed at agent creation).
3007 InvalidParamValue ChangeAgentParam supplied a value that failed the parameter's own validation (e.g., out-of-range sampling temperature, or a malformed GBNF grammar). The message field describes the constraint.
3008 InvalidExitTarget Defined for an exit field that names a node not in the graph, but not currently returned: the server reports that case as 3003 GraphCompilationFailed, with a message naming the source node, the exit, and the missing target. An empty exit field routes to END and is valid.
3009 StorageOutsideRoot A node's string_storage or embedded_string_storage parameter is an absolute path, or a relative path that escapes the process storage root (--storage-root / storage_root / mode default) via .. traversal. Returned by CreateAgentRequest, and by CreateEmbeddedStringStorageRequest for a config_path that escapes the root.
3010 StorageFileNotFound A node's storage path resolves inside the storage root but the file does not exist on disk at agent-creation time. Returned by CreateAgentRequest. CreateStringStorageRequest with a file_path and CreateVoiceInputRequest with a hotwords_storage_path return 3010 for any load failure, including a path outside the root.
3011 StorageKindMismatch A node that requires Map-kind storage (e.g. IntentToInstruction) was given a .txt (List) or Multimap file. Returned by CreateAgentRequest.
3012 AgentNotPaused ResumeAgentRequest arrived while the agent was idle or actively running (not paused). See Pause and resume a turn.
3013 UnknownVariable An UpdateAgentVariablesRequest write targeted a variable name not declared in CreateAgentRequest.variables. (An undeclared name in a template/filter fails earlier as 3003 GraphCompilationFailed.)
3014 VariableTypeMismatch An UpdateAgentVariablesRequest Assign/AddToSet/RemoveFromSet value's type did not match the variable's declared type.
3015 InvalidVariableValue An invalid variable declaration (CreateAgentRequest.variables: bad name grammar, duplicate name, or an over-limit name/string/set), an unknown variable op, a missing or over-limit update value, or a set that would exceed its 4096-element cap.
3016 InvalidToolResults ResumeAgentRequest.tool_results is not a complete, unique batch for the agent's currently paused AwaitResult tool calls: an unknown or already-completed call_id, a batch sent on a non-AwaitResult pause, or a batch exceeding the size limits (64 entries; 128 bytes/call_id; 256 KiB/result; 512 KiB aggregate). The turn stays paused for retry.
3017 ModelLanguageUnsupported Raised when a speaking agent's voice is set (CreateAgent, SetAgentVoice) and its profile has no lang of its own, and at CreateVoiceInput for the STT model, when the model does not support the session language. Fix by picking a model that covers the language, setting the voice profile's own lang, or changing the session locale. Not raised when the model declares no languages at all, or when no node of the agent speaks.
3018 DialogSnapshotInvalid Export/import snapshot is malformed, missing required fields, or has inconsistent tool call/result data. Import leaves the existing dialog unchanged.
3019 DialogFormatUnsupported Snapshot format_version is newer than this server, or the file identifier is not TDLG.
3020 DialogGraphMismatch Import Strict: graph_signature does not match the agent's create-time graph.
3021 DialogSnapshotTooLarge Encoded snapshot would overflow the 1 MiB frame cap. Unity and Unreal also return this locally when the snapshot cannot be framed; the connection stays up. Tryll never truncates.
3022 DialogUnsupportedComponent Unknown component type on export, or unknown union arm on import.
3023 InvalidVoiceProfile The voice profile in CreateAgentRequest or SetAgentVoiceRequest failed validation: an empty or unknown tts_model_name, a model that failed to load, an out-of-range value, a missing clip file, a bad or duplicate delivery-mode name, or a field the model cannot use (for example reference_voice on Supertonic 3, or a non-empty lang on a fixed-language model). The message names the field and, for a delivery mode, the mode.
3024 UnknownDeliveryMode SetAgentDeliveryModeRequest named a mode the agent's voice does not define. neutral is always accepted. The active mode is unchanged.
3025 AgentVoiceRequired CreateAgentRequest has a Speak or GenerateAndSpeak node but no voice. Also returned by SetAgentVoice and SetAgentDeliveryMode for an agent created without a voice.

Recovery:

  • 3001 — recreate the agent with CreateAgentRequest; do not retry the original request against the bad id.
  • 3003 — fix the graph and re-create. The message field points at the first node-level failure.
  • 3004 — the rejected send is an ErrorResponse only; no TurnComplete follows it. If the turn is still running, wait for its TurnComplete before sending again. If the turn is paused, waiting does not help: send ResumeAgentRequest to continue it or CancelRequest to abandon it (a pause with a pause_timeout_ms also ends when the timeout expires). The message says which case applies. The Tryll client libraries re-queue that line and flush it when the busy window closes.
  • 3005 — check the node name spelling; it must match a name declared in the original GraphDescription.
  • 3006 — remove the attempt to set that parameter; structural fields (exit routes, node type) cannot change after agent creation.
  • 3007 — correct the value against the constraints described in message and re-send the ChangeAgentParam request.
  • 3008 — not currently returned. A missing exit target arrives as 3003: fix the exit field on the offending node's params so it names an existing node (or leave it empty for END), then re-create the agent.
  • 3009 — use a relative path that stays within the process storage root; never pass an absolute path or .. components.
  • 3010 — verify the file exists at the path specified, under the process storage root (--storage-root / storage_root / mode default).
  • 3011 — use the correct file type for the node: IntentToInstruction requires a .json Map file, not a .txt list.
  • 3023 — fix the field named in message and re-create the agent, or re-send SetAgentVoice. A failed SetAgentVoice leaves the old voice in place. See Voice Profile.
  • 3024 — use a mode the profile defines, or neutral. The agent keeps speaking in its current mode.
  • 3025 — pass a voice profile when you create the agent. An agent created without one cannot be given a voice later; destroy and re-create it.
  • 3016 — resend ResumeAgentRequest.tool_results with exactly one result per pending call_id (from the tool_call event), within the size limits; the turn is still paused, so retry is safe. See Pause and resume a turn.

4xxx — Inference / workflow

Errors raised while a turn runs, by dedicated KV-cache operations, and by voice-input requests. A turn that fails is reported as 4001 InferenceFailed followed by a TurnComplete with TurnStatus::Error; the agent remains usable and can accept the next turn. The voice-input codes (4100–4107) are ErrorResponses to the voice-input request itself: they do not end a turn and do not affect the agent. 4108 and 4109 are raised by the client's voice input component before any request is sent.

Code Name Meaning
4001 InferenceFailed A Generate or other inference node raised a non-recoverable runtime error (tokenizer failure, backend crash, model unloaded unexpectedly), or TTS synthesis failed (message = "TTS synthesis failed"; the turn still completes).
4002 InferenceTimeout Defined but not currently returned. Nodes have no per-node time budget.
4003 MaxStepsExceeded Defined but not currently returned. When the workflow exceeds the maximum number of node transitions for one turn, the server sends 4001 with the message "Max steps per turn (…) exceeded", then TurnComplete with TurnStatus::Error. Usually indicates an unterminated loop in the graph.
4004 KvCacheOperationFailed Explicit KV-cache prefill, or agent creation with kv_cache_initialization = Prefill, failed while allocating, formatting, or decoding a reusable prefix.
4005 KvCacheManagementUnsupported The selected inference backend does not support the requested KV-cache lifecycle operation.
4100 SttModelLoadFailed A CreateVoiceInputRequest referenced an STT (or VAD) model that could not be loaded — not on disk, or the STT engine failed to initialise it.
4101 AudioFormatUnsupported Audio pushed to an open utterance is not in a format the STT engine accepts (sample rate / channel / encoding).
4102 VoiceInputNotFound A voice-input request targeted a handle that does not exist (never created, or already destroyed).
4103 UtteranceInProgress BeginUtterance was called while an utterance is already open on that handle.
4104 NoActiveUtterance EndUtterance / CancelUtterance / audio push arrived with no utterance open.
4105 UtteranceTimeout Defined but not currently returned. When an open utterance exceeds max_utterance_ms, the server flushes and closes it as if EndUtterance had been sent, without sending an error.
4106 HotwordBiasDisabled The voice input supplied a hotwords lexicon for a model this session turned hotword biasing off on. Refused rather than ignored, so a lexicon never silently does nothing. Either drop the lexicon or set that model's hotword bias to on.
4107 InvalidHotwordsScore hotwords_score was not a finite, non-negative number. It reaches the recognizer's beam search as a per-token bonus, where a NaN or an infinity produces garbled output with nothing in the log — so it is refused rather than clamped.
4108 MicrophoneUnavailable Client-side only; the server never sends it. The voice input component found no usable microphone: none present, the configured device is not connected, or its capture stream would not open. message names the cause; the component's microphone status says the same.
4109 VoiceInputStarting Client-side only; the server never sends it. BeginUtterance did not start because the component is (re)creating its voice input: a microphone appeared after creation was skipped, or (Unreal) the default device's sample rate changed under a live voice input. Not a failure; try again shortly.

Recovery: for 4001 during a turn, the turn ends with the TurnComplete that follows; surface the error to the user or retry the user's message. For 4004 / 4005, the failed request is a dedicated KV-cache operation rather than a turn: keep the agent, inspect the message, and retry only after resolving the underlying resource or backend issue. For 4100–4107, only the voice-input request failed: fix the model, audio format, handle, or hotword settings named in message and retry that request. For 4108, keep text input working and offer voice again later: the next BeginUtterance re-checks the microphone and recreates the voice input once one is present. For 4109, just call BeginUtterance again a moment later.


5xxx — Protocol / framing

Most 5xxx codes mean the server could not make sense of a frame the client sent — a client bug or a version mismatch, with no automated recovery. 5003 FrameTooLarge is also synthesized locally on Unity and Unreal when an outbound payload cannot be framed: that one request fails and the connection stays up, so the caller can retry with a smaller payload. 5004 ProtocolVersionMismatch is raised only by the client.

Code Name Meaning
5001 MalformedMessage The frame could not be decoded against the FlatBuffers schema.
5002 UnknownMessageType The frame's message-type tag is not in the server's known set.
5003 FrameTooLarge A frame would exceed the fixed 1 MiB (1 048 576-byte) payload cap. The server returns it when a response it built cannot be framed. An inbound frame with an out-of-range length is not answered with 5003: the server closes the connection. Unity and Unreal fail an oversized outbound request with this code and keep the connection; only a socket I/O error drops the session.
5004 ProtocolVersionMismatch Client-side only; the server never sends it. The client compared ConnectionReady.protocol_version with its own version, found they differ, and failed the connection. Upgrade the client or server so both speak the same version.
5005 DebugCommandsUnavailable A DebugCommandRequest arrived but the debug-command channel is not compiled into this build (Production) or is disabled in config.
5006 UnknownDebugCommand A DebugCommandRequest.command is not a recognised verb.

Recovery: for a local outbound 5003, shrink the request and retry; the session is still usable. For the other 5xxx codes — log, escalate, and investigate. See the wire protocol reference for the framing contract.


6xxx — Model download

The server was unable to download a model. All 6xxx codes are user-actionable: fix the underlying condition (network, disk, catalog) and retry.

Code Name Meaning
6001 DownloadFailed The download transport failed (HTTP error, interrupted transfer, checksum mismatch).
6002 DownloadNotAvailable The named model has no HuggingFace repo/files configured, so there is nothing to download (e.g. a local_path-only entry).
6003 InsufficientDiskSpace The target download directory lacks free space for the model.
6004 DownloadAlreadyActive A download for this model is already in progress on the server.
6005 ModelResolutionFailed The named model is not in the catalog, or the engine it needs is not registered. Returned by LoadModel and DeleteModel (e.g. LoadModel for a VAD-only catalog entry), and when CreateEmbeddedStringStorage cannot resolve its embedding model. A graph model missing at CreateAgent is 3003 instead (see the note below).
6007 ModelPlacementUnavailable Reserved; not currently returned. Placement requests are hints and do not fail: the server downgrades a placement it cannot satisfy and reports the resolved placement instead.
6008 EngineNotAvailable A referenced model needs an engine that is not registered in this server build.
6009 ModelManagementDisabled This deployment mode does not download or delete models (Client Prod / Standalone). Ship every model with the game.

Note

6006 (ModelAutoDownloadFailed) is retired along with the removed auto-model-downloading feature and will not be reused. A missing model referenced by CreateAgent / CreateEmbeddedStringStorage / CreateVoiceInput now surfaces as GraphCompilationFailed (3003), ModelResolutionFailed (6005), or SttModelLoadFailed (4100) instead. A missing TTS model named by the agent's voice surfaces as InvalidVoiceProfile (3023).

Recovery:

  • 6001 — retry after checking connectivity.
  • 6002 — ask the server admin to add a matching variant to the catalog (see Use Your Own Local Model), or request a different model.
  • 6003 — free disk space or reconfigure models_root.
  • 6004 — wait for the in-flight download's completion frame instead of re-issuing.
  • 6009 — do not call DownloadModel / DeleteModel in Client Prod; stage Production models at build time.

7xxx — String storage

Errors raised by CreateStringStorageRequest, CreateEmbeddedStringStorageRequest, and by the session storage manager at registration time. The session is unchanged on failure; the storage is not created.

Code Name Meaning
7001 InvalidStringStorageName The storage name is empty, malformed, or reserved, or (on destroy) no storage with that name exists.
7002 StringStorageAlreadyExists A storage with this name is already registered for the session.
7003 InvalidStringStorageData The content was rejected: unreadable file, bad format, empty array.
7004 StorageNameInUse The virtual name passed to an inline (strings-based) CreateStringStorageRequest or CreateEmbeddedStringStorageRequest resolves to an existing real file under the storage root. The name is rejected to prevent the virtual entry from silently shadowing the file. Use a name that does not match any filename under the process storage root.

Recovery: fix the name or content and re-send the request. For 7004, choose a virtual name that does not correspond to any file under the process storage root. See the string storage reference.


8xxx — Embedded string storage

Errors raised by mutable knowledge bases (named memory stores, their snapshots, save and load). CreateEmbeddedStringStorageRequest does not return 8xxx: a failed create returns 7001–7004 (name or content) or 6005 (embedding model cannot be resolved). The session is unchanged on failure.

Code Name Meaning
8001 InvalidEmbeddedStorageName A mutable store name is empty, malformed, or reserved.
8002 EmbeddedStorageAlreadyExists Defined, but not currently returned.
8003 EmbeddedStorageBuildFailed A mutable store could not be created, loaded, or restored (for example its embedding model or snapshot could not be used).
8101 StorageBusy Export/import/save/load refused because an agent is not strictly idle (running, paused, or in a KV-cache operation).
8102 SchemaMismatch The named store already exists under a different schema.
8103 MaxRecordsExceeded An insert was rejected because the schema max_records cap is reached.
8104 UnknownSchema The schema name is not in schemas.json, or the schema file failed to load.
8105 MutableKbSnapshotInvalid The TMKB buffer failed verification, is missing required fields, or has an unsupported format_version.
8106 StorageSnapshotTooLarge The encoded snapshot exceeds MaxMutableKbSnapshotBytes (wire) or MaxGameMemorySnapshotBytes (file).
8107 InvalidEmbedTiming LoadGameMemory used Unspecified; callers must pass Now or Lazy.
8108 UnknownMutableKb The named store does not exist (read/write/export without EnsureMutableKb).
8109 SavesDisabled SaveGameMemory / SaveDialog refused because saves.enabled is false (config or --disable-saves). Load* still work.

Recovery: fix the config, schema, or snapshot and re-send the request. See the embedded string storage reference and Save and load agent state.


Client-side handling

Every Tryll client library delivers these codes through its error channel:

  • C++ — Tryll::Client::ErrorCode plus an std::string message on the on_error callback.
  • Python — raised as tryll_client.TryllError with .code and .message attributes, or delivered to the async callback.
  • Unity — TryllError value struct with Code (int) and Message (string) fields; IsOk is true when Code == 0. All …Async methods return Task<(T result, TryllError error)>; callers must check error.IsOk before using the result.
  • Unreal — FTryllError USTRUCT with Code and Message properties; the ETryllErrorCode UENUM matches this table.