Exceptions
In shortException hierarchy for graph execution, storage, timeouts, and media validation errors.
- 10 min read
- 14 sections
- Updated
- v0.10.0
- Markdown
10xGraph raises typed exceptions that distinguish retryable storage failures from permanent errors, execution faults from control flow, and capability mismatches from input corruption. Most carry an error code and a context dict, and serialize to a dictionary through to_dict(). This page lists every class in tenxgraph.core.exceptions, with signatures, defaults and examples.
from tenxgraph.core.exceptions import (
GraphError,
GraphRecursionError,
GraphStopRequested,
MetricsError,
NodeError,
NodeTimeoutError,
ResourceNotFoundError,
SchemaVersionError,
SerializationError,
StaleStateError,
StorageError,
TransientStorageError,
)
# Not re-exported from the package, import it from its module
from tenxgraph.core.exceptions.media_exceptions import UnsupportedMediaInputErrorException hierarchy and API status codes
Most 10xGraph exceptions carry an error_code, a message and a context dict, and share a to_dict() method. When you run the API server, its error handlers map each class to an HTTP status, shown below. Subclasses fall under their parent’s handler unless the table lists them.
Exception
GraphError
NodeError
NodeTimeoutError
GraphRecursionError
GraphStopRequested
StorageError
TransientStorageError
SerializationError
SchemaVersionError
StaleStateError
ResourceNotFoundError
MetricsError
UnsupportedMediaInputError| Exception | HTTP status from the API server |
|---|---|
| GraphError, NodeError, NodeTimeoutError, GraphRecursionError | 500 |
| StorageError, SerializationError, ResourceNotFoundError | 500 |
| TransientStorageError | 503 |
| SchemaVersionError | 422 |
| StaleStateError | 409 |
| MetricsError | 500 |
str(error) returns "[error_code] message". Each constructor also logs the error on the tenxgraph.exceptions logger.
GraphError
Base exception for graph-related errors.
Signature
class GraphError(Exception):
def __init__(
self,
message: str,
error_code: str = "GRAPH_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Human-readable description of the error. |
| error_code | str | "GRAPH_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information (JSON-serializable). |
Attributes
| Name | Type | Description |
|---|---|---|
| message | str | The error message. |
| error_code | str | The error code. |
| context | dict[str, Any] | Contextual data. |
Methods
| Name | Return | Description |
|---|---|---|
| to_dict() | dict[str, Any] | Returns structured error with error_type, error_code, message, and context. |
Example
from tenxgraph.core.exceptions import GraphError
try:
raise GraphError(
message="Invalid graph structure",
error_code="GRAPH_001",
context={"node_count": 5},
)
except GraphError as e:
print(e.to_dict())
# {'error_type': 'GraphError', 'error_code': 'GRAPH_001', ...}NodeError
Exception for node-specific errors; inherits from GraphError.
Signature
class NodeError(GraphError):
def __init__(
self,
message: str,
error_code: str = "NODE_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the node error. |
| error_code | str | "NODE_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Base class: GraphError
Example
from tenxgraph.core.exceptions import NodeError
raise NodeError(
message="Node failed to execute",
error_code="NODE_001",
context={"node_name": "process_data"},
)NodeTimeoutError
Raised when a node or tool exceeds its allotted execution time; inherits from NodeError.
Timing out a hanging node (a half-open socket in an MCP tool, a custom tool that never returns) converts indefinite hangs into recoverable node errors that the execution loop can persist and retry.
Signature
class NodeTimeoutError(NodeError):
def __init__(
self,
message: str,
error_code: str = "NODE_TIMEOUT_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the timeout. |
| error_code | str | "NODE_TIMEOUT_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Base class: NodeError
Example
from tenxgraph.core.exceptions import NodeTimeoutError
raise NodeTimeoutError(
message="Node 'fetch' exceeded its 300s timeout",
error_code="NODE_TIMEOUT_001",
context={"node_name": "fetch", "timeout": 300.0},
)GraphRecursionError
Raised when graph execution exceeds the recursion limit; inherits from GraphError.
The default recursion limit is 25. Exceeding it typically indicates an infinite loop or misconfigured conditional routing.
Signature
class GraphRecursionError(GraphError):
def __init__(
self,
message: str,
error_code: str = "RECURSION_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the recursion error. |
| error_code | str | "RECURSION_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information (e.g., recursion_depth, max_depth). |
Base class: GraphError
Example
from tenxgraph.core.exceptions import GraphRecursionError
raise GraphRecursionError(
message="Recursion limit exceeded",
error_code="RECURSION_001",
context={"recursion_depth": 26, "max_depth": 25},
)GraphStopRequested
Signals that a stop was requested while a node was still running; not a failure but control flow.
This is raised internally to distinguish a cooperative stop from a genuine error. The execution loop catches it, marks the run stopped, persists that state, and returns normally without raising.
Signature
class GraphStopRequested(Exception):
def __init__(self, node_name: str | None = None) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| node_name | str | None | None | Name of the node that was running when stop was requested. |
Attributes
| Name | Type | Description |
|---|---|---|
| node_name | str | None | The name of the node, if known. |
Example
from tenxgraph.core.exceptions import GraphStopRequested
# Typically raised by the execution loop during stop handling
raise GraphStopRequested(node_name="fetch_data")StorageError
Base exception for non-retryable storage layer errors; inherits from Exception.
Provides structured error handling with error codes and context. Subclasses distinguish retryable transient failures from permanent ones.
Signature
class StorageError(Exception):
def __init__(
self,
message: str,
error_code: str = "STORAGE_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the error. |
| error_code | str | "STORAGE_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Attributes
| Name | Type | Description |
|---|---|---|
| message | str | The error message. |
| error_code | str | The error code. |
| context | dict[str, Any] | Contextual data. |
Methods
| Name | Return | Description |
|---|---|---|
| to_dict() | dict[str, Any] | Returns structured error with error_type, error_code, message, and context. |
Example
from tenxgraph.core.exceptions import StorageError
raise StorageError(
message="Database connection failed",
error_code="STORAGE_001",
context={"host": "db.example.com"},
)TransientStorageError
Retryable storage error (connection drops, timeouts); inherits from StorageError.
These errors indicate temporary failures that may succeed on retry. The caller should retry with exponential backoff. The API server returns HTTP 503 for it.
Signature
class TransientStorageError(StorageError):
def __init__(
self,
message: str,
error_code: str = "STORAGE_TRANSIENT_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the transient error. |
| error_code | str | "STORAGE_TRANSIENT_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Base class: StorageError
Example
from tenxgraph.core.exceptions import TransientStorageError
raise TransientStorageError(
message="Redis connection timeout",
error_code="STORAGE_TRANSIENT_001",
context={"timeout": 5.0},
)SerializationError
Raised when serialization or deserialization of state and messages fails; inherits from StorageError.
This is a permanent failure in data marshaling, not a transient issue. It typically indicates corrupted data or a schema mismatch.
Signature
class SerializationError(StorageError):
def __init__(
self,
message: str,
error_code: str = "STORAGE_SERIALIZATION_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the serialization error. |
| error_code | str | "STORAGE_SERIALIZATION_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Base class: StorageError
Example
from tenxgraph.core.exceptions import SerializationError
raise SerializationError(
message="Failed to deserialize message content",
error_code="STORAGE_SERIALIZATION_001",
context={"message_id": "msg_123"},
)SchemaVersionError
Raised when schema version detection or migration fails; inherits from StorageError.
This indicates a mismatch between the database schema and the code expectations, typically during startup or upgrade.
Signature
class SchemaVersionError(StorageError):
def __init__(
self,
message: str,
error_code: str = "STORAGE_SCHEMA_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the schema version error. |
| error_code | str | "STORAGE_SCHEMA_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Base class: StorageError
Example
from tenxgraph.core.exceptions import SchemaVersionError
raise SchemaVersionError(
message="Database schema version 3 not supported by code version 2.0",
error_code="STORAGE_SCHEMA_001",
context={"db_version": 3, "code_version": 2},
)StaleStateError
Raised when a durable state write loses an optimistic-concurrency check; inherits from StorageError.
The writer based its update on a state version that is no longer current because another execution committed a newer state for the same thread in the meantime. Committing anyway would silently discard that other execution’s work, so the write is rejected. The caller should reload the latest state and retry.
Signature
class StaleStateError(StorageError):
def __init__(
self,
message: str,
error_code: str = "STORAGE_CONFLICT_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the concurrency conflict. |
| error_code | str | "STORAGE_CONFLICT_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information (e.g., thread_id, expected_version, actual_version). |
Base class: StorageError
API response: HTTP 409 Conflict
Example
from tenxgraph.core.exceptions import StaleStateError
raise StaleStateError(
message="State was updated by another execution",
error_code="STORAGE_CONFLICT_001",
context={"thread_id": "thread_abc", "expected_version": 5, "actual_version": 6},
)ResourceNotFoundError
Raised when a requested resource is not found in storage; inherits from StorageError.
Signature
class ResourceNotFoundError(StorageError):
def __init__(
self,
message: str,
error_code: str = "STORAGE_NOT_FOUND_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the not found error. |
| error_code | str | "STORAGE_NOT_FOUND_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information (e.g., thread_id, resource_type). |
Base class: StorageError
Example
from tenxgraph.core.exceptions import ResourceNotFoundError
raise ResourceNotFoundError(
message="Thread not found",
error_code="STORAGE_NOT_FOUND_001",
context={"thread_id": "thread_xyz"},
)MetricsError
Raised when metrics emission fails; inherits from Exception.
Metrics failures are typically non-critical and should be logged but not propagated. Catch and log it rather than letting it stop a run.
Signature
class MetricsError(Exception):
def __init__(
self,
message: str,
error_code: str = "METRICS_000",
context: dict[str, Any] | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| message | str | Required | Description of the metrics error. |
| error_code | str | "METRICS_000" |
Unique error code for categorization. |
| context | dict[str, Any] | None | None | Additional contextual information. |
Attributes
| Name | Type | Description |
|---|---|---|
| message | str | The error message. |
| error_code | str | The error code. |
| context | dict[str, Any] | Contextual data. |
Methods
| Name | Return | Description |
|---|---|---|
| to_dict() | dict[str, Any] | Returns structured error with error_type, error_code, message, and context. |
Example
from tenxgraph.core.exceptions import MetricsError
try:
raise MetricsError(
message="Failed to send metrics to collector",
error_code="METRICS_001",
context={"collector": "prometheus"},
)
except MetricsError:
# Log and continue; do not fail execution
passUnsupportedMediaInputError
Raised when a provider or model cannot accept a given media input; inherits from Exception.
This error is raised before the provider call when the target model does not support the media type or no viable transport path exists. If you omit message, one is built from the other parameters and ends with a suggestion, such as using a vision-capable model for images or uploading the file first for URLs.
Signature
class UnsupportedMediaInputError(Exception):
def __init__(
self,
provider: str,
model: str,
media_type: str,
source_kind: str,
transports_attempted: list[MediaTransportMode] | None = None,
message: str | None = None,
) -> None: ...Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| provider | str | Required | Provider identifier (e.g. “openai”, “google”, “anthropic”). |
| model | str | Required | Model name (e.g. “gpt-4o”, “gemini-1.5-pro”). |
| media_type | str | Required | Type of media (e.g. “image”, “document”, “audio”). |
| source_kind | str | Required | How the media was provided: “url”, “file_id”, “data”, or “internal_ref”. |
| transports_attempted | list[MediaTransportMode] | None | None | List of transport modes that were tried before giving up. |
| message | str | None | None | Custom error message; if None, one is built from the parameters. |
Attributes
| Name | Type | Description |
|---|---|---|
| provider | str | Provider identifier. |
| model | str | Model name. |
| media_type | str | Type of media. |
| source_kind | str | Source kind (url, file_id, data, internal_ref). |
| transports_attempted | list[MediaTransportMode] | The transports that were attempted. |
| message | str | The error message. |
Methods
| Name | Return | Description |
|---|---|---|
| to_dict() | dict[str, Any] | Returns error_type, provider, model, media_type, source_kind, transports_attempted (as a list of string values), and message. |
Example
from tenxgraph.core.exceptions import UnsupportedMediaInputError
from tenxgraph.storage.media.capabilities import MediaTransportMode
raise UnsupportedMediaInputError(
provider="openai",
model="gpt-4o",
media_type="audio",
source_kind="url",
transports_attempted=[MediaTransportMode.remote_url],
)