rfgen.errors

The exception hierarchy for the framework. Every error rfgen raises is a subclass of RfgenError, which lets callers catch all framework faults with a single except clause while still discriminating on more specific subclasses when handling retries, validation, or plugin-lookup failures.

Every subclass carries a structured context: dict[str, object] attribute that downstream telemetry can read. The values are JSON-serializable so log sinks can emit them as-is. str(err) returns the top-level message; the full context is available via err.context.

Module summary

from rfgen.errors import (
    RfgenError,
    ConfigError,
    PluginNotFoundError,
    BackendUnavailableError,
    StorageError,
    CommitConflictError,
)

try:
    pipeline.run(cfg)
except BackendUnavailableError as exc:
    raise SystemExit(f"missing optional dep: {exc}")
except PluginNotFoundError as exc:
    raise SystemExit(f"missing plugin: {exc}")
except ConfigError as exc:
    raise SystemExit(f"invalid config: {exc}")
except RfgenError as exc:
    log.exception("rfgen pipeline failed: %s", exc)
    raise

The hierarchy is one level deep apart from RegistryError’s two specializations, the manifest-validation chain, and StorageError’s publication-conflict specialization. Two subclasses (BackendUnavailableError, InferenceError) carry extra structured fields beyond the base context attribute.

Class index

Class

Parent

Notes

RfgenError

Exception

Root exception; carries context: dict[str, object]

ConfigError

RfgenError

Hydra/Pydantic config failed validation or composition

ValidationError

RfgenError

Runtime validation contract violated

RTAssetValidationError

ValidationError

Ray-tracing material or antenna asset violates the strict Layer 28 boundary

ManifestValidationError

ValidationError

Run-manifest envelope or payload violates its structural contract

UnsupportedSchemaVersionError

ManifestValidationError

Persisted run manifest uses an unsupported schema major

RegistryError

RfgenError

Plugin registry encountered a structural problem (e.g., duplicate registration)

PluginNotFoundError

RegistryError

Registry lookup miss; message lists available names

PluginVersionError

RegistryError

Plugin’s declared version is incompatible with the framework

EmitterError

RfgenError

Emitter-layer synthesis failure

ChannelError

RfgenError

Channel-layer impairment-application failure

SceneError

RfgenError

Scene composer cannot complete composition

LabelError

RfgenError

Labeler failed to derive labels

AnnotationError

RfgenError

Annotator failed to produce text

StorageError

RfgenError

Storage backend persistence failure

CommitConflictError

StorageError

Manifest LATEST compare-and-swap observed a different revision

IOError

RfgenError

rfgen-side I/O path failure (downloads, fixture loads, manifests). Shadows the built-in IOError

DeterminismError

RfgenError

Determinism invariant violated at runtime

BackendUnavailableError

RfgenError

An optional rfgen[<extra>] dep was required but not installed

InferenceError

RfgenError

Inference-backend response failed schema, vocabulary, or empty-response validation

PlacementError

RfgenError

Placement strategy could not satisfy its constraints

The shipped class set lives at src/rfgen/errors.py and is exported via rfgen.errors.__all__. Adding or removing a subclass is a breaking change for any caller that catches by specific type.


class rfgen.errors.RfgenError(Exception)

Root of the rfgen exception hierarchy. Every framework-raised exception subclasses this.

class RfgenError(Exception):
    def __init__(
        self,
        message: str = "",
        *,
        context: dict[str, Any] | None = None,
    ) -> None: ...

Attributes

Attribute

Type

Purpose

context

dict[str, Any]

Structured key/value attachments. JSON-serializable so log sinks can emit them as-is. Defaults to {} when no context kwarg is passed

Notes

  • Subclasses inherit __init__ unchanged unless they override it. BackendUnavailableError and InferenceError are the only two that override.

  • Every public callable in the framework (any callable exported via a module’s __all__) lists in its docstring Raises: section the exact RfgenError subclasses it can raise. A contract test in validation-and-audit walks every public callable, parses the docstring with docstring_parser>=0.16 (Google style), AST-walks the implementation source for raise <Name>(...) nodes, and asserts the AST set equals the docstring set. Standard-library exceptions raised by callees are not in scope.


class rfgen.errors.ConfigError(RfgenError)

Raised when a Hydra/Pydantic config fails validation or composition.

The canonical entry point that surfaces this is validate_config (in rfgen.config), which catches pydantic.ValidationError and re-raises as ConfigError(message=str(exc), context={"errors": json.loads(exc.json())}) from exc. from_hydra raises ConfigError directly for non-config / non-dict / ListConfig inputs (with a Hydra-specific message). See Reference / API / Config for both.

ConfigError.context["errors"] is a JSON-serializable list of Pydantic error entries. Coercion is delegated to Pydantic’s ValidationError.json() so non-serializable ctx values (e.g., raw ValueError instances raised inside custom @model_validators) become string-serialized in a single step.


class rfgen.errors.ValidationError(RfgenError)

Raised when a runtime validation contract is violated. Distinct from ConfigError, which is reserved for config-time failures.

The manifest-specific subclasses are ManifestValidationError and UnsupportedSchemaVersionError.


class rfgen.errors.ManifestValidationError(ValidationError)

Raised when a run-manifest envelope or payload violates its structural contract. parse_manifest wraps invalid UTF-8 JSON, envelope validation, missing required payload fields, and payload validation failures in this exception. See Manifest for the persisted contract.

class rfgen.errors.UnsupportedSchemaVersionError(ManifestValidationError)

Raised by parse_manifest when the envelope major differs from MANIFEST_SCHEMA_MAJOR. Its context carries the supported and received schema-major values.


class rfgen.errors.RegistryError(RfgenError)

Raised when the plugin registry encounters a structural problem (e.g., duplicate registration under the same name). The message names both the existing source module and the incoming source module so the conflict is debuggable.

The two specializations under RegistryError are PluginNotFoundError (lookup miss) and PluginVersionError (version incompatibility).

class rfgen.errors.PluginNotFoundError(RegistryError)

Raised when a registry is asked for a plugin name that is not registered. The message lists the available names for that registry’s group.

class rfgen.errors.PluginVersionError(RegistryError)

Raised when a plugin’s declared version (parsed via packaging.version.Version) is incompatible with the framework’s pinned range.


class rfgen.errors.EmitterError(RfgenError)

Raised by the emitter layer (Layer 3) for synthesis-side failures. Examples: a backend SDK returned an unexpected shape, a pre-recorded capture failed checksum, a parameter combination is out of the documented support region.

class rfgen.errors.ChannelError(RfgenError)

Raised by the channel layer (Layer 3) for impairment-application failures. Examples: a Sionna RT scene fails to converge, a polyphase resampler hits a non-rational rate ratio, an RX-frontend backend rejects an out-of-band parameter.

class rfgen.errors.SceneError(RfgenError)

Raised by the scene composer (Layer 5) when scene composition cannot complete. Examples: density constraints unsatisfiable, placement budget exhausted, RT geometry blob missing.

class rfgen.errors.LabelError(RfgenError)

Raised by the labeler (Layer 6) when label derivation fails. Examples: bbox cannot be derived from a malformed Signal, segmentation mask shape mismatches the IQ tensor.

class rfgen.errors.AnnotationError(RfgenError)

Raised by the annotator (Layer 7) when annotation generation fails. Distinct from InferenceError, which targets inference-backend response-validation failures specifically.

class rfgen.errors.StorageError(RfgenError)

Raised by storage backends (Layer 6) for persistence failures. Examples: bucket access denied, schema mismatch on read, atomic-shard commit failed.

class rfgen.errors.CommitConflictError(StorageError)

Raised when a manifest publication compare-and-swap cannot proceed because manifests/LATEST no longer equals the caller’s expected revision. The error context records expected_latest and observed_latest; the repository leaves the visible pointer unchanged. See ManifestRepository for the retry and reconciliation contract.

class rfgen.errors.IOError(RfgenError)

Raised by rfgen-side I/O paths: dataset downloads, fixture loads, manifest reads, etc.

This class shadows the built-in IOError. Code that needs the built-in should import it explicitly as import builtins; builtins.IOError. The acceptance contract for the errors module enumerates IOError as a required RfgenError subclass; the override is intentional, not an accident.

class rfgen.errors.DeterminismError(RfgenError)

Raised when a determinism invariant is violated at runtime. Examples: a contract test that re-runs seed_for(...) and observes a different output, a backend that bypassed derive_rng and pulled from global RNG state.

class rfgen.errors.PlacementError(RfgenError)

Raised by placement strategies (Layer 4) when they cannot satisfy their constraints (e.g., requested density too high for the available band, no admissible time slots given the scene duration).


class rfgen.errors.BackendUnavailableError(RfgenError)

Raised when an optional rfgen[<extra>] dependency is required but not installed. Carries missing_import, extra, and (optionally) class_name as both keyword-only constructor args and as inherited attributes.

class BackendUnavailableError(RfgenError):
    def __init__(
        self,
        *,
        missing_import: str,
        extra: str,
        class_name: str | None = None,
        message: str | None = None,
        context: dict[str, Any] | None = None,
    ) -> None: ...

    missing_import: str
    extra: str
    class_name: str | None

Behavior

  • Default message when class_name is None: f"Optional dependency '{missing_import}' is not installed. Install it with \pip install rfgen[{extra}]`.”`

  • Default message when class_name is set: f"{class_name} requires the '{extra}' extra. Install it with \pip install rfgen[{extra}]`.”This is the documented format for raise sites that know their own class name (e.g., each cloud provider inrfgen.credentials`).

  • context automatically merges {"missing_import": <name>, "extra": <name>} (plus "class_name" when supplied) with any caller-supplied additional keys.

  • Each cloud provider in rfgen.credentials (see Reference / API / Credentials) raises this from its __init__ passing class_name=type(self).__name__ so the message reads e.g. "GcpADCProvider requires the 'gcp' extra. Install it with \pip install rfgen[gcp]`.”`


class rfgen.errors.InferenceError(RfgenError)

Raised when an inference-backend response fails validation. The class wraps any inference backend (text, vision-language, audio-language); the name was generalized from the earlier LLMResponseError so the protocol stays modality-agnostic. Carries template_id, run_id, and failure_summary as both keyword-only constructor args and as inherited attributes.

class InferenceError(RfgenError):
    def __init__(
        self,
        *,
        template_id: str,
        run_id: str,
        failure_summary: str,
        message: str | None = None,
        context: dict[str, Any] | None = None,
    ) -> None: ...

    template_id: str
    run_id: str
    failure_summary: str

Behavior

  • Default message: f"Inference response failed validation: {failure_summary}".

  • context automatically merges {"template_id": ..., "run_id": ..., "failure_summary": ...} with any caller-supplied additional keys.

  • Failure modes (failure_summary values) typically fall into three documented buckets: schema mismatch (the response did not match the prompt’s json_schema), vocabulary violation (the response used terms outside the prompt’s ClosedVocab), or empty response (the backend returned no usable content).


See Also


Legacy class names

Several pre-implementation drafts of the framework named errors differently. The shipped hierarchy collapsed or renamed those classes; the anchors below redirect old cross-references to the current shipped surface so other doc pages render. Layer 3+ doc pages still reference these old names; they will be updated when the corresponding layers reconcile.

Legacy: ConfigurationError

Renamed to ConfigError in the shipped rfgen.errors module.

Legacy: UnsupportedConfiguration

Removed from the shipped surface. Plugin code that cannot satisfy a requested config combination raises ConfigError (config-time) or ValidationError (runtime).

Legacy: GenerationError

Removed from the shipped surface. The shipped hierarchy exposes per-layer typed errors directly: EmitterError, ChannelError, SceneError. Catch RfgenError for an umbrella.

Legacy: LabelComputeError

Collapsed into LabelError in the shipped surface. The structured context carries the failure-mode discriminator the legacy subclass used to encode by type.

Legacy: LabelInconsistencyError

Collapsed into LabelError in the shipped surface. context["reason"] distinguishes the inconsistency mode (bbox / segmentation / metadata disagreement).

Legacy: LLMError

Collapsed into InferenceError in the shipped surface. Network and transport failures surface via the underlying SDK exception; rfgen wraps response-validation failures only.

Legacy: LLMRateLimitError

Removed from the shipped surface. Rate-limit handling is the responsibility of the inference client wrapper (rfgen.inference Layer 7), which surfaces SDK-native rate-limit exceptions or wraps them in InferenceError with failure_summary="rate_limited".

Legacy: LLMRefusalError

Collapsed into InferenceError in the shipped surface, with failure_summary="refused" in the structured context.

Legacy: HallucinationError

Collapsed into InferenceError in the shipped surface, with failure_summary="hallucination" and the verifier-rejected text in context["rejected_text"].

Legacy: LLMResponseError

Renamed to InferenceError in the shipped surface. The class wraps any inference backend (text, vision-language, audio-language), so the name was generalized.

Legacy: StorageTransientError

Collapsed into StorageError in the shipped surface. Retryable failures are distinguished by context["retryable"] = True; the storage backend wraps the underlying SDK exception in this attribute.

Legacy: StoragePermanentError

Collapsed into StorageError in the shipped surface. Non-retryable failures are distinguished by context["retryable"] = False.