baldur — Exceptions
The fifteen top-level exceptions: domain base classes plus the leaf classes
raised by the top-level public surface. Everything else stays in
baldur.core.exceptions.
BaldurError
BaldurError(message: str = '', *, code: str = '')
Bases: Exception
Base exception for all baldur library errors.
extra_context
extra_context() -> dict[str, Any]
Return structlog-bindable context. Override in subclasses.
AdapterError
AdapterError(message: str = '', *, code: str = '')
AdapterNotFoundError
AdapterNotFoundError(
message: str = "",
*,
adapter_type: str = "",
adapter_name: str = "",
code: str = ""
)
CircuitBreakerError
CircuitBreakerError(message: str = '', *, code: str = '')
DLQError
DLQError(message: str = '', *, code: str = '')
DLQReplayError
DLQReplayError(message: str = '', *, code: str = '')
ResilienceError
ResilienceError(message: str = '', *, code: str = '')
RetryExhaustedError
RetryExhaustedError(message: str = '', *, code: str = '')
TimeoutPolicyError
TimeoutPolicyError(
timeout_seconds: float, message: str = ""
)
RateLimitExceeded
RateLimitExceeded(
message: str = "",
*,
key: str = "",
limit: int = 0,
window_seconds: int = 0,
reset_at: int = 0
)
Bases: ResilienceError
Raised by @rate_limit when a call is rejected by the limiter.
Function-level rejection signal — distinct from
RateLimitStorageError (storage-backend failure).
LLMUnavailableError
LLMUnavailableError(
message: str = "",
*,
attempts: tuple[tuple[str, str], ...] = ()
)
Bases: ResilienceError
Raised by a baldur.llm.wrap client when no endpoint answered the call.
Every endpoint was tried in order — each with its own waits, retries and
breaker — and each was rate-limited, overloaded, out of quota, refused the
key, failed, or stood behind an open breaker. The last endpoint's error is
chained as __cause__.
It is the one error a job sees for "the provider could not answer right
now": under @protected(..., dlq=True) it is parked under the job's name,
and with replay=True the job is re-run when its breaker closes. It is
not retried by an enclosing retry stage: every endpoint already ran its own
retries, so running them all again would only multiply calls to providers
that are refusing them.
Attributes:
| Name | Type | Description |
|---|---|---|
attempts |
|
IdempotencyDuplicateError
IdempotencyDuplicateError(
message: str = "",
*,
key: str = "",
domain: str = "",
decision: str = ""
)
Bases: BaldurError
Raised by @idempotent on a detected duplicate or in-flight collision.
Inherits BaldurError directly (correctness contract, not a
resilience stage). Non-retryable by default — outer @dlq_protect
layers should treat this as a terminal signal.
IdempotencyUnavailableError
IdempotencyUnavailableError(
message: str = "", *, key: str = "", error: str = ""
)
Bases: BaldurError
Raised when an idempotency check cannot complete due to a cache I/O failure (e.g. Redis unreachable) on an enabled, explicitly-requested gate.
Distinct from IdempotencyDuplicateError (a successful dedup verdict):
this signals the verdict is unknown, so the caller can assume neither
"safe to skip" nor "safe to run". Fail-closed by default — opt into
fail-open via BALDUR_IDEMPOTENCY_FAIL_OPEN_ON_CACHE_ERROR or the per-call
idempotency_fail_open=True. Wraps the original cache exception (raised
from it) so a backend-specific error never leaks across the boundary.
DomainValidationError
DomainValidationError(
message: str = "",
*,
original_domain: str = "",
reason: Any = None
)
Bases: BaldurError
Raised when a domain input string fails validation.
Carries the original (pre-normalization) input and a typed reject reason for downstream logging / metric labelling.
Modeled on RecoveryAdapterError: raised at validation sites that have
a loud failure mode (decoration-time, where a CI/dev surface can recover
via test or rename). Runtime APIs catch this and fall back to
FALLBACK_DOMAIN instead of propagating.
ConfigurationError
ConfigurationError(message: str = '', *, code: str = '')