Errors
IdentificationGate
Section titled “IdentificationGate”IdentificationGateOverlap/positivity policy for an observational comparison.
Defaults refuse rather than silently proceed when propensities are
extreme (overlap="trim" opts in to dropping poor overlap
instead). min_propensity bounds a symmetric band: a fitted
propensity outside [min_propensity, 1 - min_propensity] trips.
IdentificationError
Section titled “IdentificationError”IdentificationError(message, code, context)Identification gate refused: the data cannot support the requested estimand.
Every call site names its own stable dotted code and carries structured context; there is no generic default.
CapabilityError
Section titled “CapabilityError”CapabilityErrorRaised when a source cannot honestly provide a requested capability.
Errors and refusals
Section titled “Errors and refusals”Typed errors and refusal specifications describe invalid definitions, unsupported requests, and wire-format failures.
An arm-lift readout with no observed treatment arm raises
InvalidRequestError with code readout.arms.no_treatment. Its context
identifies control_group and observed_arms; supply at least one
non-control arm to estimate a contrast. This does not prevent reading
arm-level counts or running an otherwise defined allocation diagnostic.
Heterogeneity estimation checks its identification contract before reading
outcomes. InvalidRequestError codes and their context:
cate.identification.randomized_only(caller,mechanism):estimate_cateneeds a randomized source.cate.identification.unsupported_mechanism(caller,mechanism,supported): the design is neither randomized nor observational.cate.identification.unsupported_missing_policy(caller,missing): an observational design must declaremissing="refuse"for this path.cate.identification.unsupported_max_smd(caller,max_smd): the observationalmax_smdbalance gate is not implemented for this path.
CodedError
Section titled “CodedError”CodedError(message, code, context)A public error carrying a stable code and immutable call context.
CodedModel, CodedValidationMixin and unwrap_coded are public from
increment.errors, not the root increment namespace.
CodedModel and every definition model in increment.semantics.models
(which use CodedValidationMixin) surface coded validator refusals from direct
construction and direct model_validate, model_validate_json, and
model_validate_strings calls: a declaration refused by one of its own
validators raises its DefinitionError with its code. Pydantic schema
boundaries such as TypeAdapter and an ordinary BaseModel containing one of
these models still raise ValidationError: Pydantic captures the refusal
because CodedError intentionally remains compatible with ValueError.
Recover the coded refusal explicitly at those boundaries:
Only CodedModel (including Definitions) also translates declared-field
Field constraint failures: they raise
InvalidRequestError (a ValueError), with a model.field.* code, rather
than pydantic.ValidationError. Code that catches validation failures from
these models must catch (pydantic.ValidationError, increment.errors.InvalidRequestError) (or ValueError) rather than
replacing one with the other. Uncoded-validator, root-level, and nested
non-coded-model failures remain ValidationError, as do plain field
constraints on the other definition models.
from pydantic import TypeAdapter, ValidationError
from increment.errors import DefinitionError, unwrap_codedfrom increment.semantics.models import Definitions
try: TypeAdapter(Definitions).validate_python({"day_boundary": "EST"})except ValidationError as exc: try: unwrap_coded(exc) except DefinitionError as coded: refusal = {"code": coded.code, "context": dict(coded.context)} else: raiseCodedModel
Section titled “CodedModel”CodedModel(data)Mixin that translates attributable pydantic field failures to coded errors.
Direct construction and model_validate* calls surface
InvalidRequestError for known field failures, while cross-field
validators and unknown pydantic failure kinds remain ValidationError.
DefinitionError
Section titled “DefinitionError”DefinitionError(message, code, context)A definition YAML parse, model validation, or reference failed.
Carries message, the file or directory path given to the
loader, and a copied sources mapping for duplicate-name errors.
InvalidRequestError
Section titled “InvalidRequestError”InvalidRequestErrorRaised when a public request is invalid.
RefusalSpec
Section titled “RefusalSpec”RefusalSpec(code, error_type, render, template, keys)Stable code, exception type, and renderer for one refusal.
Exactly one of render (a callable, for text that needs computation)
or template (a str.format string, for plain interpolation) must be
set. keys is the template’s own {placeholder} names, unioned with
any explicitly declared extras; a render-only spec’s keys stays
empty — its own call signature is its drift guard.
RETIRED_CODES
Section titled “RETIRED_CODES”RETIRED_CODESLookup only: maps a retired refusal code to its canonical replacement,
to a tuple of replacements when one code was split into several, or to
None if the code was deleted with no replacement (a genuinely dead
registration). Every retired/merged/deleted code in this codebase
gets exactly one entry here in the same change that removes it from the
live registry. A CodedError instance’s own .code never changes after
construction — this map is for callers who catch an old code and need
to migrate, and for tests/test_retired_codes.py’s enforcement.
UnsupportedRequestError
Section titled “UnsupportedRequestError”UnsupportedRequestErrorRaised when a recognized request is not supported.
WireFormatError
Section titled “WireFormatError”WireFormatErrorRaised when serialized source data has an invalid wire format.
refuse
Section titled “refuse”refuse(spec, context)Render one refusal and raise its declared coded error type.
refusals
Section titled “refusals”refusals(error_type, entries)Build a code -> RefusalSpec registry. Each entry is a plain
str.format template, a (template, extra_keys) pair (for a template
whose caller-supplied keys are not all used as placeholders), or a
prebuilt RefusalSpec (passed through unchanged, its own code must
match the registry key).
raiser
Section titled “raiser”raiser(registry)Build a module’s _raise(code, **context) from its registry.
unwrap_coded
Section titled “unwrap_coded”unwrap_coded(exc)Re-raise the first coded refusal buried in a pydantic ValidationError.
Use this at schema boundaries such as TypeAdapter or an ordinary
BaseModel containing a CodedModel. Returns (does nothing) if no
coded error is found, so the caller can re-raise the original
ValidationError unchanged.
Warnings
Section titled “Warnings”Library advisories are instances of IncrementWarning (or
IncrementRuntimeWarning/IncrementDeprecationWarning, which also satisfy
filterwarnings/pytest.warns matched against RuntimeWarning/
DeprecationWarning), carrying a stable .code and immutable .context
alongside the free-text message — the warning counterpart to CodedError.
Filter or assert on .code rather than message text:
import warnings
from increment.errors import IncrementWarning
with warnings.catch_warnings(record=True) as caught: warnings.simplefilter("always") ... # a call that may emit a library advisorycodes = {w.message.code for w in caught if isinstance(w.message, IncrementWarning)}IncrementWarning
Section titled “IncrementWarning”IncrementWarning(message, code, context)A public warning carrying a stable code and immutable call context.
Mirrors CodedError: .code is fixed at construction and .context
is an immutable snapshot. A category that must also match
RuntimeWarning/DeprecationWarning for existing filterwarnings
calls should multiply-inherit from this class and that category
(see IncrementRuntimeWarning, IncrementDeprecationWarning) rather
than replacing it.
IncrementRuntimeWarning
Section titled “IncrementRuntimeWarning”IncrementRuntimeWarningA coded warning that also satisfies filterwarnings(category=RuntimeWarning).
IncrementDeprecationWarning
Section titled “IncrementDeprecationWarning”IncrementDeprecationWarningA coded warning that also satisfies filterwarnings(category=DeprecationWarning).
WarningSpec
Section titled “WarningSpec”WarningSpec(code, warning_type, render)Stable code, warning type, and renderer for one coded warning.
warn(spec, stacklevel, skip_file_prefixes, context)Render one coded warning and emit it via warnings.warn.
context is a single explicit mapping (never **kwargs) so a local
_warn(code, /, **context) forwarding helper can pass it straight
through as context=context without a keyword-splat colliding with
stacklevel/skip_file_prefixes — the shape a type checker cannot
otherwise rule out through a **kwargs: object splat.
stacklevel means the same thing it would at a direct warnings.warn
call: this function adds its own frame to warnings.warn’s count
internally (stacklevel + 1), so a caller need not account for going
through warn() itself. A local _warn(code, /, *, stacklevel=2, **context) helper that forwards to this function should do the same
(warn(spec, stacklevel=stacklevel + 1, context=context)) to absorb
its own frame — callers at the original warnings.warn sites then
keep their original numeric stacklevel literal unchanged.