tenro.errors¶
Exceptions raised by Tenro when your agent doesn't behave as expected.
What errors mean¶
When a Tenro verification fails, it means your agent didn't behave as expected:
from tenro import Provider, link_tool
from tenro.simulate import llm, tool
from tenro.testing import tenro
@link_tool("search")
def search(query: str) -> list[str]:
return api.search(query)
@tenro
def test_agent_searches_before_responding():
tool.simulate(search, result=["doc1"])
llm.simulate(Provider.OPENAI, response="Summary")
my_agent.run("Find info")
# If this fails, your agent didn't call search the expected number of times
tool.verify_many(search, count=1)
If verify_tool fails, you'll see:
This tells you: Your agent didn't call the search tool. Fix your agent code, not the test.
Exception types¶
| Exception | Meaning | Example |
|---|---|---|
TenroVerificationError |
Agent didn't behave as expected | Tool called wrong number of times |
TenroConfigError |
Test setup is invalid | Unknown provider name |
TenroSimulationSetupError |
Simulation couldn't be applied | Missing required simulation |
Common error messages¶
"Expected tool 'X' to be called N times, but was called M times"¶
Your agent called a tool more or fewer times than expected. Check your agent logic.
"No simulation configured for provider 'X'"¶
You forgot to simulate the LLM before running your agent:
from tenro import Provider
from tenro.simulate import llm
from tenro.testing import tenro
@tenro
def test_agent():
# Missing: llm.simulate(Provider.OPENAI, response="...")
my_agent.run("query") # Fails - no simulation for OpenAI
"Unused simulation for tool 'X'"¶
You simulated a tool your agent never called. Either your agent has a bug, or remove the unnecessary simulation.
Reference¶
Exceptions and warnings for Tenro SDK.
SimulationDiagnostic
dataclass
¶
Structured diagnostic information for simulation errors.
Provides machine-readable fields for tooling and human-readable messages.
Source code in tenro/errors/simulation.py
failure_reason
instance-attribute
¶
Technical explanation of why the operation failed.
is_linked
instance-attribute
¶
Whether the target is a linked callable (@link_tool, @link_agent, @link_llm).
recommended_fix
instance-attribute
¶
Actionable guidance for resolving the error.
target_path
instance-attribute
¶
Canonical path of the simulation target (e.g., 'mymodule.my_tool').
target_type
instance-attribute
¶
Type of the target (e.g., 'function', 'method', 'class', 'builtin').
TenroAgentError
¶
Bases: TenroError
Base exception for agent-related errors.
TenroAgentRecursionError
¶
Bases: TenroAgentError
Raised when agent exceeds maximum nesting depth.
This usually indicates an infinite loop between agents (e.g., Agent A calls Agent B, which calls Agent A again).
TenroCoercionWarning
¶
Bases: TenroWarning
Emitted when ToolCall() automatically converts a value to JSON-serializable format.
This helps catch unexpected coercions. If you expect the coercion, silence with: warnings.filterwarnings("ignore", category=TenroCoercionWarning)
Source code in tenro/errors/warnings.py
TenroConfigError
¶
Bases: TenroError
Raised when configuration or setup is invalid.
TenroConfigWarning
¶
Bases: TenroWarning
Emitted for non-fatal configuration issues.
The SDK continues operating but behavior may not match expectations.
TenroConstructError
¶
Bases: TenroError
Base exception for Construct test harness errors.
TenroDeprecationWarning
¶
Bases: TenroWarning, DeprecationWarning
Emitted when using a deprecated API that will be removed.
Inherits from both TenroWarning (for SDK filtering) and DeprecationWarning (for standard Python filtering behavior).
Source code in tenro/errors/warnings.py
TenroError
¶
TenroFutureWarning
¶
Bases: TenroWarning, FutureWarning
Emitted when behavior will change in an upcoming release.
Inherits from both TenroWarning (for SDK filtering) and FutureWarning (for standard Python filtering behavior).
TenroLateImportWarning
¶
Bases: TenroWarning
Emitted when modules are imported before Tenro can patch them.
Best-effort patching is applied but stale references may exist. Import tenro before other libraries to avoid this warning.
TenroMissingLLMCallError
¶
Bases: TenroVerificationError
Raised when a linked LLM function doesn't call the provider.
The decorated function executed but no HTTP request was made to the LLM provider, so the configured simulation was never used.
Source code in tenro/errors/base.py
TenroPatchingWarning
¶
Bases: TenroWarning
Emitted when PatchEngine fails to install in non-strict mode.
The SDK continues operating but simulation may not work correctly for captured function references. Use --tenro-strict-patch to make patching failures fatal.
Source code in tenro/errors/warnings.py
TenroPluginWarning
¶
Bases: TenroWarning
Emitted when a provider plugin fails to load.
Other plugins continue loading; only the failing plugin is skipped.
TenroProviderConfigError
¶
Bases: TenroConfigError
Raised when provider configuration is invalid.
TenroProviderRuntimeError
¶
Bases: TenroError
Raised when a provider encounters a runtime error.
TenroSimulationCoverageError
¶
Bases: TenroVerificationError
Raised when simulation coverage requirements are not met.
Coverage errors indicate incomplete test execution where expected simulations were not triggered.
TenroSimulationExecutionError
¶
Bases: TenroError
Raised when simulation execution produces unexpected callable kind.
This error occurs at call time when a simulation rule's side_effect or configured response produces the wrong type for the wrapper's expected kind:
- Sync wrapper expects non-awaitable, non-generator value
- Async wrapper expects awaitable
- Generator wrapper expects Generator
- Async generator wrapper expects AsyncGenerator
Attributes:
| Name | Type | Description |
|---|---|---|
expected_kind |
The callable kind the wrapper expected. |
|
actual_kind |
The callable kind that was produced. |
|
target_path |
The simulation target's canonical path. |
Source code in tenro/errors/simulation.py
__init__
¶
Initialize with kind mismatch information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_path
|
str
|
The simulation target's canonical path. |
required |
expected_kind
|
str
|
Expected kind (sync/async/gen/asyncgen). |
required |
actual_kind
|
str
|
Actual kind that was produced. |
required |
Source code in tenro/errors/simulation.py
TenroSimulationSetupError
¶
Bases: TenroConfigError
Raised when simulation setup fails due to invalid target.
This error occurs during simulate() calls when the target cannot be
simulated. Common causes:
- Target is not decorated with @link_tool, @link_agent, or @link_llm
- Target is a builtin or C-extension that cannot be intercepted
- Target identity cannot be resolved
Attributes:
| Name | Type | Description |
|---|---|---|
diagnostic |
Structured diagnostic with target info and fix suggestions. |
Source code in tenro/errors/simulation.py
__init__
¶
__init__(message: str, diagnostic: SimulationDiagnostic) -> None
Initialize with message and diagnostic info.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Human-readable error message. |
required |
diagnostic
|
SimulationDiagnostic
|
Structured diagnostic information. |
required |
Source code in tenro/errors/simulation.py
not_linked
classmethod
¶
not_linked(target_path: str, target_type: str = 'function') -> TenroSimulationSetupError
Create error for non-linked target.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_path
|
str
|
The target's dotted path or repr. |
required |
target_type
|
str
|
Type of the target (function, method, class, etc.). |
'function'
|
Returns:
| Type | Description |
|---|---|
TenroSimulationSetupError
|
Configured error with diagnostic. |
Source code in tenro/errors/simulation.py
not_patchable
classmethod
¶
not_patchable(target_path: str, reason: str, target_type: str = 'function') -> TenroSimulationSetupError
Create error for non-patchable target (registered function simulation).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_path
|
str
|
The target's dotted path or repr. |
required |
reason
|
str
|
Why the target is not patchable. |
required |
target_type
|
str
|
Type of the target (function, method, class, etc.). |
'function'
|
Returns:
| Type | Description |
|---|---|
TenroSimulationSetupError
|
Configured error with diagnostic. |
Source code in tenro/errors/simulation.py
TenroSimulationUsageError
¶
Bases: TenroConfigError
Raised when simulation API is used incorrectly.
This error is raised when simulate() is called without an active Construct context. All simulation calls must be made within a Construct context.
Source code in tenro/errors/base.py
TenroTracingWarning
¶
Bases: TenroWarning
Emitted when tracing cannot be applied to a linked component.
The component still functions but without extended tracing.
TenroUnexpectedLLMCallError
¶
Bases: TenroVerificationError
Raised when an unmatched request hits a blocked LLM domain.
This error protects against accidentally calling real LLM APIs during tests. If a request to a known LLM provider (e.g., api.openai.com) is made without a matching simulation, this error is raised immediately.
Attributes:
| Name | Type | Description |
|---|---|---|
domain |
The blocked domain that was accessed (e.g., "api.openai.com"). |
|
url |
The full URL of the blocked request. |
Source code in tenro/errors/base.py
__init__
¶
Initialize with domain and URL information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
domain
|
str
|
The blocked domain (e.g., "api.openai.com"). |
required |
url
|
str
|
The full URL of the blocked request. |
required |
Source code in tenro/errors/base.py
TenroUnusedSimulationError
¶
Bases: TenroVerificationError
Raised when a simulation was registered but never triggered.
The simulate_llm() call set up a simulation, but the code path that would
trigger it was never executed.
TenroUnusedSimulationWarning
¶
Bases: TenroWarning
Emitted when a simulation was registered but never triggered.
The simulation was set up but the code path that would trigger it
was never executed. Use optional=True to suppress this warning
for intentionally optional simulations.
Source code in tenro/errors/warnings.py
TenroValidationError
¶
Bases: TenroError
Raised when API usage or parameters are invalid.
TenroVerificationError
¶
Bases: AssertionError
Raised when test verification fails.
Inherits from AssertionError so pytest shows FAIL (not ERROR), matching expected test semantics.
TenroWarning
¶
Bases: UserWarning
Base warning for all Tenro SDK warnings.
Use this to filter all SDK warnings at once.
Example
import warnings warnings.filterwarnings("ignore", category=TenroWarning)
warn
¶
warn(message: str, category: type[Warning] = TenroWarning, *, stacklevel: int = 2) -> None
Emit a Tenro warning pointing to the caller's location.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Warning message to display. |
required |
category
|
type[Warning]
|
Warning category class. Defaults to TenroWarning. |
TenroWarning
|
stacklevel
|
int
|
Stack frames to skip. Default (2) points to the caller of the function that calls warn(). Increase for nested helpers. |
2
|
Source code in tenro/errors/warnings.py
See also¶
- Construct: Test harness that raises these exceptions
- Testing patterns: Error handling patterns