Skip to content

mostlyright.core.exceptions

Structured exception hierarchy for the mostlyright SDK and MCP server.

Every exception subclasses MostlyrightError and exposes a MostlyrightError.to_dict() method that returns a JSON-safe dict suitable for placement in the MCP error.data field of a JSON-RPC error response. Attributes mirror the design doc §D + §R contract; payload values are coerced via mostlyright.core._json_safe.to_json_safe() so the returned dict survives json.dumps without further customization.

Role names for SourceMismatchError are standardized at "observations", "forecasts", "settlement" (per design.md §R). The column-prefix abbreviations obs_ / fcst_ / settle_ are NOT valid role names.

DATA_AVAILABILITY_REASONSShared reason enum — MUST match TS lockstep.
DataAvailabilityReasonType alias kept loose (str) rather than typing.Literal so callers passing a string variable don’t need to cast().
CaptureNotAvailableError([message, …])A webcast has no cold-fetchable HTTP media asset to capture.
ContractError([message, field, expected, …])A frame or source spec violates its declared contract.
DataAvailabilityError([message, source, …])Typed exception for “I tried to fetch and got nothing usable”.
DeprecatedModelWarningWarning emitted when a deprecated NWP model is fetched.
EarningsError([message, error_code, source, …])Base class for earnings-mention pipeline errors.
EarningsFactCorruptError([message, …])An earnings fact row violates a column / identity contract.
ExperimentalFeatureWarningWarning emitted when an EXPERIMENTAL, semver-exempt surface is first used.
GOESDataCorruptError([message, error_code, …])NetCDF missing required attributes/variables, or shape unexpected.
GOESS3Error([message, error_code, source, …])S3 (or GCS mirror) access failure after retries exhausted.
GRIBIntegrityError([message, variable, …])A fetched GRIB2 byte-range failed structural / integrity validation.
HistoricalDepthError([message, …])A requested NWP cycle is older than the archive’s depth.
IndicatorNotYetReleasedError(indicator, …)A requested economic release is EXPECTED but has not been published yet.
IssuedAtMissingError([message, source, …])A forecast row is missing the issued_at field.
KalshiCountRuleViolationError([message, …])A Kalshi-counted occurrence carries an un-anchorable provenance.
LabelAlignmentError([message, namespace, …])A user-supplied (BYO) label frame violated the aligner contract.
LeakageError([message, sample_violations, …])Temporal leakage detected — at least one row has knowledge_time greater than the asserted as_of cutoff.
LiveStreamError([message, cause, source, …])Base class for mostlyright.live.stream / live.latest failures.
MostlyrightError([message, error_code, …])Base class for all mostlyright structured errors.
NWPError([message, error_code, source, …])Base class for NWP forecast errors.
NWPModelNotAvailableError([message, …])Model is declared in the public enum but not implemented in this version.
NWPModelRetiredError([message, model, …])Caller asked for a model past its retirement date.
NoCWOPDataError(station, reason, *[, …])No CWOP (APRS-IS) data available for the requested station/area.
NoDataError([message, cause, source, …])No usable data was produced for the requested entity/window.
NoLiveDataError([message, request_id, …])mostlyright.live.latest() returned no observations for the station.
NoLiveForNWPError([message, mirrors_tried, …])All wired mirrors failed to serve a live cycle for (model, cycle).
OpenMeteoSeamlessLeakageError([message, …])The Open-Meteo Historical Forecast (seamless) endpoint was used without allow_leakage=True opt-in.
PayloadTooLargeError([message, …])The MCP server rejected an inline payload whose declared size exceeded the cap.
ProductNotRegisteredError([message, …])(product, variable) pair not in the PRODUCTS registry.
SatelliteError([message, error_code, …])Base class for GOES ABI L2 satellite ingest errors.
SchemaValidationError([message, violations, …])A DataFrame failed schema validation.
SourceMismatchError([message, role, …])The data’s source does not match the schema’s registered source, and the caller did not opt out via source_drift_reason.
SourceUnavailableError([message, source, …])A source (HTTP endpoint, vendored parser, etc.) returned an error or was otherwise unreachable.
StationOutOfGridError([message, error_code, …])Station projection lands outside the product grid.
StormNotFoundError([message, query, …])A HAFS storm query (id or name) doesn’t match any active storm.
TemporalDriftError([message, …])Raised by the reproducibility audit (design.md §P) when one or more rows have retrieved_at outside the asserted range AND fall within the volatile window of now.
UnitsContractError([message, error_code, …])NetCDF variable units attribute does not match the registry.

exception mostlyright.core.exceptions.CaptureNotAvailableError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.CaptureNotAvailableError(message=”, , error_code=None, source=None, request_id=None)”

Bases: EarningsError

A webcast has no cold-fetchable HTTP media asset to capture.

Raised by a capture adapter when the provider template is not an HTTP-media webcast — e.g. Q4’s analyst template is a telephone dial-in bridge (Meeting ID + passcode; zero media/CDN hosts ever fire — RESEARCH §2 CHWY). The correct disposition is to route to dial-in / demand capture or skip, NOT to silently emit empty audio. This is a normal control signal (the conference-call subclass), not a corruption — a subclass of EarningsError so callers filter it cleanly.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.ContractError(message=”, , field=None, expected=None, actual=None, location=None, doc_url=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.ContractError(message=”, , field=None, expected=None, actual=None, location=None, doc_url=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

A frame or source spec violates its declared contract.

Modelled on SchemaValidationError but for the two-axis align(spine, *sources) world: raised when a SourceContract is malformed (e.g. a prefix that does not end with "_") or when a source/spine frame does not conform at compose time. field names the offending contract field so the copy (built via mostlyright._errmsg.contract_message()) points the user at the exact thing to change.

  • Parameters:
    • message (str)
    • field (str | None)
    • expected (str | None)
    • actual (str | None)
    • location (str | None)
    • doc_url (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

mostlyright.core.exceptions.DATA_AVAILABILITY_REASONS : tuple[str, …] = (‘model_unavailable’, ‘out_of_window’, ‘cache_miss’, ‘source_404’, ‘source_5xx’, ‘rate_limited’)

Section titled “mostlyright.core.exceptions.DATA_AVAILABILITY_REASONS : tuple[str, …] = (‘model_unavailable’, ‘out_of_window’, ‘cache_miss’, ‘source_404’, ‘source_5xx’, ‘rate_limited’)”

Shared reason enum — MUST match TS lockstep. The TS exception in packages-ts/core/src/exceptions/index.ts defines an identical array under DATA_AVAILABILITY_REASONS. Drift here invalidates every cross-SDK except DataAvailabilityError as e: if e.reason == ... branch a consumer writes.

exception mostlyright.core.exceptions.DataAvailabilityError(message=”, , reason, hint, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.DataAvailabilityError(message=”, , reason, hint, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

Typed exception for “I tried to fetch and got nothing usable”.

Replaces overloaded SourceUnavailableError raise sites across several paths (forecast model unavailable, AWC outside 168h, IEM cache miss, fetcher 404/5xx, rate-limit). Consumers branch on reason instead of string-matching message:

try: : df = tw.research(…)

except DataAvailabilityError as e: : if e.reason == “out_of_window”: : … # widen the window
elif e.reason == “rate_limited”: : … # back off
else: : raise

The reason enum is shared lockstep with the TypeScript SDK — see DATA_AVAILABILITY_REASONS and the matching const array in packages-ts/core/src/exceptions/index.ts. Drift between SDKs is the load-bearing risk.

SourceUnavailableError remains in place for back-compat; new code prefers DataAvailabilityError.

  • Parameters:
    • message (str)
    • reason (str)
    • hint (str)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

mostlyright.core.exceptions.DataAvailabilityReason

Section titled “mostlyright.core.exceptions.DataAvailabilityReason”

Type alias kept loose (str) rather than typing.Literal so callers passing a string variable don’t need to cast(). Construction-time validation in DataAvailabilityError.__init__ enforces the enum.

exception mostlyright.core.exceptions.DeprecatedModelWarning

Section titled “exception mostlyright.core.exceptions.DeprecatedModelWarning”

Bases: DeprecationWarning

Warning emitted when a deprecated NWP model is fetched.

Used for NAM / HREF / HiResW which retire 31 Aug 2026 per NWS scn26-47 (Herbie issue #540). Subclass of DeprecationWarning so callers can promote it to an error via warnings.filterwarnings("error", category=DeprecatedModelWarning).

exception mostlyright.core.exceptions.EarningsError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.EarningsError(message=”, , error_code=None, source=None, request_id=None)”

Bases: MostlyrightError

Base class for earnings-mention pipeline errors.

Covers the canonical earnings schemas (schema.finance.transcript.v1 / schema.finance.fact.v1) and their contract hooks. Subclasses map a single failure mode of the fact-ledger build path. Mirrors the SatelliteError / NWPError block discipline.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.EarningsFactCorruptError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.EarningsFactCorruptError(message=”, , error_code=None, source=None, request_id=None)”

Bases: EarningsError

An earnings fact row violates a column / identity contract.

Raised by the schema hooks (e.g. validate_ticker()) when a row’s ticker or other contract field is malformed — mirrors GOESDataCorruptError / validate_satellite_station.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.ExperimentalFeatureWarning

Section titled “exception mostlyright.core.exceptions.ExperimentalFeatureWarning”

Bases: UserWarning

Warning emitted when an EXPERIMENTAL, semver-exempt surface is first used.

The contributor registry (mostlyright.experimental.contributor()) is public-experimental and semver-exempt until it graduates — its contribute() protocol, registry surface, and compose semantics may change in any minor release. This warning fires ONCE per session, on the FIRST third-party registration (the four built-in contributors — forecasts / trades / satellite / cwop — are exempt so the default dataset() path stays warning-free).

Subclass of UserWarning (NOT DeprecationWarning) because the feature is not being removed — it is provisional. Callers who want to treat experimental usage as an error can promote it via warnings.filterwarnings("error", category=ExperimentalFeatureWarning).

exception mostlyright.core.exceptions.GOESDataCorruptError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.GOESDataCorruptError(message=”, , error_code=None, source=None, request_id=None)”

Bases: SatelliteError

NetCDF missing required attributes/variables, or shape unexpected.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.GOESS3Error(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.GOESS3Error(message=”, , error_code=None, source=None, request_id=None)”

Bases: SatelliteError

S3 (or GCS mirror) access failure after retries exhausted.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.GRIBIntegrityError(message=”, , model, variable=None, byte_offset=None, byte_end=None, underlying=”, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.GRIBIntegrityError(message=”, , model, variable=None, byte_offset=None, byte_end=None, underlying=”, request_id=None, error_code=None)”

Bases: NWPError

A fetched GRIB2 byte-range failed structural / integrity validation.

Raised when the GRIB2 record retrieved via byte-range does not match its .idx claim, decodes with missing variables, or cfgrib surfaces an “unexpected end of message” / “messages out of order” error. Carries the variable that triggered the error plus the (byte_offset, byte_end) of the offending record so the caller can replay or skip.

  • Parameters:
    • message (str)
    • model (str)
    • variable (str | None)
    • byte_offset (int | None)
    • byte_end (int | None)
    • underlying (str)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.HistoricalDepthError(message=”, , model, requested_cycle=None, archive_depth=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.HistoricalDepthError(message=”, , model, requested_cycle=None, archive_depth=None, request_id=None, error_code=None)”

Bases: NWPError

A requested NWP cycle is older than the archive’s depth.

Each NWP model has an AWS BDP archive depth (HRRR from 30 Jul 2014, GFS from 1 Jan 2021, GEFS from 1 Jan 2017, NBM from 2020, ECMWF IFS from 1 Jan 2022, AIFS from 25 Feb 2024). MSC family always raises (24h Datamart retention) — pass archive_depth=None for the live-only case.

  • Parameters:
  • Return type: None

Model id (e.g. "hrrr", "hrdps").

UTC datetime the caller asked for.

Earliest cycle the archive holds, or None for live-only models (MSC 24h retention, NOMADS-only legacy).

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.HttpError(message, status_code=None)

Section titled “exception mostlyright.core.exceptions.HttpError(message, status_code=None)”

Bases: MostlyrightError

Base exception for mostlyright HTTP-layer errors.

Subclass of MostlyrightError so catching MostlyrightError also catches transport errors. The HTTP-layer status_code attribute is the only transport-specific attribute; structured error_code / source / request_id flow through MostlyrightError.__init__.

  • Parameters:
    • message (str)
    • status_code (int | None)

exception mostlyright.core.exceptions.IndicatorNotYetReleasedError(indicator, period, , expected_release=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.IndicatorNotYetReleasedError(indicator, period, , expected_release=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

A requested economic release is EXPECTED but has not been published yet.

In the economy vertical, “not yet released” is a normal, branchable control state distinct from “unavailable” — the release calendar says a print is due, but vintage_time for that period does not exist yet. The economy surface (economy.history / economy.releases / economy.research_economy) raises this instead of returning [] / None so a caller can tell “the data is genuinely gone” (a DataAvailabilityError) apart from “come back after the 8:30 ET drop” (this error) and, when known, retry at expected_release.

Lives in the core hierarchy (not packages/economy) for the same reason EarningsError / NoCWOPDataError do: the exception taxonomy is centralized so MCP JSON-RPC serialization and the Python↔TS lockstep discipline apply uniformly. mostlyright.economy re-exports it.

  • Parameters:
    • indicator (str)
    • period (str)
    • expected_release (datetime | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

The indicator id ("cpi", "nfp", "gdp", …).

The observation period requested ("2026-06", "2026Q2", an FOMC meeting date, …).

The scheduled release wall-clock when known, else None (the payload never fabricates a timestamp).

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.IssuedAtMissingError(message=”, , source=None, violating_count=0, sample_violations=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.IssuedAtMissingError(message=”, , source=None, violating_count=0, sample_violations=None, request_id=None, error_code=None)”

Bases: SchemaValidationError

A forecast row is missing the issued_at field.

Raised when a forecast row would land in the DataFrame with issued_at IS NULL. For Open-Meteo Previous Runs API this should be impossible by construction (the fetcher derives issued_at per row via the conservative lower-bound formula). For Live mode, this is raised when cycle-math fallback cannot derive a non-null cycle.

Origin: Tarabcak/mostlyright#70 — the legacy seamless-feed bug where /forecast_series proxied Open-Meteo’s seamless endpoint without preserving issued_at, causing post-snapshot model runs to silently leak into training data.

  • Parameters:
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.KalshiCountRuleViolationError(message=”, , role_source=None, speaker_role=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.KalshiCountRuleViolationError(message=”, , role_source=None, speaker_role=None, source=None, request_id=None, error_code=None)”

Bases: EarningsError

A Kalshi-counted occurrence carries an un-anchorable provenance.

Raised by validate_kalshi_counted_occurrence in strict mode when an occurrence asserted as Kalshi-counted has role_source not in {transcript_structural, transcript_self_id, roster_match} OR speaker_role not in {company_executive, operator_ir} (fail-closed). Carries the offending role_source / speaker_role so callers and audit logs can see exactly why the occurrence was excluded — mirrors how StationOutOfGridError surfaces station/satellite via _payload.

  • Parameters:
    • message (str)
    • role_source (str | None)
    • speaker_role (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.LabelAlignmentError(message=”, , reason, namespace=None, column=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.LabelAlignmentError(message=”, , reason, namespace=None, column=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

A user-supplied (BYO) label frame violated the aligner contract.

Raised by mostlyright._labels.align_byo_labels() when a bring-your-own label DataFrame cannot be aligned to the station settlement calendar without ambiguity or a silent data hazard. Every rejection is LOUD — the aligner never silently drops rows, guesses a date column, or no-ops a publication-discipline request.

reason is a stable enum so a caller can branch without parsing the message text:

  • "missing_date" — no date column and no coercible datetime index.
  • "missing_station_panel" — panel call (multi-station) but the frame has no station column.
  • "station_disagree" — a single-station call whose frame carries a station column that disagrees with the call’s station.
  • "collision" — a BYO label column collides with a reserved namespace (label recipe columns, a registered feature prefix, or core obs_*/cli_* names). namespace names which one was hit.
  • "publication_lag_no_published_at"labels_as_known= "publication_lag" requested but the frame carries no published_at column (never a silent no-op).
  • Parameters:
    • message (str)
    • reason (str)
    • namespace (str | None)
    • column (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Stable rejection-reason vocabulary (BYO contract sharp edges). Shared lockstep with the TS LABEL_ALIGNMENT_REASONS.

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.LeakageError(message=”, , as_of, violating_count, sample_violations=None, column=None, boundary=None, decision_time=None, doc_url=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.LeakageError(message=”, , as_of, violating_count, sample_violations=None, column=None, boundary=None, decision_time=None, doc_url=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

Temporal leakage detected — at least one row has knowledge_time greater than the asserted as_of cutoff. Carries the count and a small sample of violating rows for actionable surfacing.

  • Parameters:
    • message (str)
    • as_of (str)
    • violating_count (int)
    • sample_violations (list [dict [str , Any ] ])
    • column (str | None)
    • boundary (str | None)
    • decision_time (str | None)
    • doc_url (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.LiveStreamError(message=”, , cause=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.LiveStreamError(message=”, , cause=None, source=None, request_id=None, error_code=None)”

Bases: NoDataError

Base class for mostlyright.live.stream / live.latest failures.

Live-streaming errors are deliberately a separate sub-tree from SourceUnavailableError because the recovery path differs — for a live stream, the caller is in a polling loop and “no data yet” is the COMMON case, not an exception. NoLiveDataError is only raised by the one-shot mostlyright.live.latest() surface; mostlyright.live.stream() swallows empty-tick errors and waits for the next polite-floor cycle.

Re-parented under NoDataError so NoLiveDataError / NoCWOPDataError live in the NoDataError sub-tree WITHOUT losing their LiveStreamError ancestry (an additive MRO change — nothing is dropped, consistent with the additive-plus-shims rule). default_error_code stays LIVE_STREAM_ERROR.

  • Parameters:
    • message (str)
    • cause (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.MostlyrightError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.MostlyrightError(message=”, , error_code=None, source=None, request_id=None)”

Bases: Exception

Base class for all mostlyright structured errors.

error_code is a stable enum (e.g. "SOURCE_UNAVAILABLE") used by callers / agents to branch on without parsing message text. source is the source ID involved ("iem.archive" etc.) when applicable, and request_id correlates an MCP JSON-RPC request when applicable.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

Return a JSON-safe dict suitable for MCP error.data.

exception mostlyright.core.exceptions.NWPError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.NWPError(message=”, , error_code=None, source=None, request_id=None)”

Bases: MostlyrightError

Base class for NWP forecast errors.

Subclasses cover the three failure modes a quant fetching live NWP data hits in practice: an unsupported model (ECMWF Tier-2 reserved for v0.2), no live cycle reachable from any wired mirror, or decoded GRIB2 bytes that failed integrity / structural validation.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.NWPModelNotAvailableError(message=”, , model, available_in=‘v0.2’, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.NWPModelNotAvailableError(message=”, , model, available_in=‘v0.2’, request_id=None, error_code=None)”

Bases: NWPError

Model is declared in the public enum but not implemented in this version.

Raised for the four ECMWF Tier-2 models (ecmwf_ifs_hres, ecmwf_ifs_ens, ecmwf_aifs_single, ecmwf_aifs_ens) which require hosted infrastructure to backfill and are deferred to v0.2. model carries the offending model id and available_in names the release that will land it.

  • Parameters:
    • message (str)
    • model (str)
    • available_in (str)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.NWPModelRetiredError(message=”, , model=”, retired_on=None, replacement_suggestions=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.NWPModelRetiredError(message=”, , model=”, retired_on=None, replacement_suggestions=None, request_id=None, error_code=None)”

Bases: NWPError

Caller asked for a model past its retirement date.

NAM / HREF / HiResW retire 31 Aug 2026 per NWS scn26-47 (Herbie issue #540). The retirement date is loaded from mostlyright.weather._fetchers._url_transitions.LEGACY_MODELS_RETIRE. Carries replacement_suggestions so callers can wire a graceful fallback (HRRR / RAP / RRFS).

  • Parameters:
    • message (str)
    • model (str)
    • retired_on (datetime | None)
    • replacement_suggestions (list [str ])
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.NoCWOPDataError(station, reason, , request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.NoCWOPDataError(station, reason, , request_id=None, error_code=None)”

Bases: NoLiveDataError

No CWOP (APRS-IS) data available for the requested station/area.

Raised by the standalone mostlyright.weather.cwop surface (scan/nearby/stream/snapshot/latest) instead of returning []/None, so callers get an actionable signal — CWOP is a live-only TCP stream and “nothing arrived” is the common failure mode (the station never reported, the area is empty, or the listen window was too short). Carries the resolved station/area identifier, the fixed source="cwop.live" tag, and a human-readable reason.

  • Parameters:
    • station (str)
    • reason (str)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.NoDataError(message=”, , cause=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.NoDataError(message=”, , cause=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

No usable data was produced for the requested entity/window.

The taxonomy base for “I asked and got nothing” across domains. NoLiveDataError / NoCWOPDataError are re-parented under this class so align/contract code can build on a stable name. The optional cause names WHICH fact failed (window empty vs entity unknown vs source gap) so a valid zero-row result is distinguishable from a broken feed (MACH-02 / DX-H5).

  • Parameters:
    • message (str)
    • cause (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.NoLiveDataError(message=”, , station, source, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.NoLiveDataError(message=”, , station, source, request_id=None, error_code=None)”

Bases: LiveStreamError

mostlyright.live.latest() returned no observations for the station.

Carries the resolved ICAO station and the canonical source identity tag ("awc.live" / "iem.live") so caller logs can branch by source without re-parsing the message.

  • Parameters:
    • message (str)
    • station (str)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.NoLiveForNWPError(message=”, , model, mirrors_tried=None, last_status=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.NoLiveForNWPError(message=”, , model, mirrors_tried=None, last_status=None, request_id=None, error_code=None)”

Bases: NWPError

All wired mirrors failed to serve a live cycle for (model, cycle).

Carries the mirror chain that was tried and the per-mirror failure summary so callers can audit why every fallback failed. Distinct from SourceUnavailableError because the recovery action is different — for NWP, the typical fix is to wait for the next cycle rather than retry the same one.

  • Parameters:
    • message (str)
    • model (str)
    • mirrors_tried (list [str ])
    • last_status (int | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.OpenMeteoSeamlessLeakageError(message=”, , model=”, endpoint_url=”, as_of=None, violating_count=0, sample_violations=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.OpenMeteoSeamlessLeakageError(message=”, , model=”, endpoint_url=”, as_of=None, violating_count=0, sample_violations=None, source=None, request_id=None, error_code=None)”

Bases: LeakageError

The Open-Meteo Historical Forecast (seamless) endpoint was used without allow_leakage=True opt-in.

The seamless endpoint silently stitches forecasts from multiple model cycles into a continuous timeseries; the cycle that produced each value is unrecoverable from the response. LeakageDetector rejects rows tagged source="open_meteo.seamless" whenever as_of is asserted.

Origin: Tarabcak/mostlyright#70.

  • Parameters:
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.PayloadTooLargeError(message=”, , declared_size, limit, accepted_modes=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.PayloadTooLargeError(message=”, , declared_size, limit, accepted_modes=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

The MCP server rejected an inline payload whose declared size exceeded the cap. accepted_modes advertises the alternatives (e.g. file-path mode per design.md §Q).

  • Parameters:
    • message (str)
    • declared_size (int)
    • limit (int)
    • accepted_modes (list [str ])
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.ProductNotRegisteredError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.ProductNotRegisteredError(message=”, , error_code=None, source=None, request_id=None)”

Bases: SatelliteError

(product, variable) pair not in the PRODUCTS registry.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.SatelliteError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.SatelliteError(message=”, , error_code=None, source=None, request_id=None)”

Bases: MostlyrightError

Base class for GOES ABI L2 satellite ingest errors.

Rehomes the 2i monorepo goes_satellite typed exceptions into the SDK’s structured hierarchy so the extractor (_goes_extract.py) and the S3 transport (_goes_s3.py) raise SDK-native errors instead of bare Exception subclasses. Each subclass maps a single failure mode of the single-pixel extraction path.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.SchemaValidationError(message=”, , schema_id, violations=None, quarantine_count=0, sample_violations=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.SchemaValidationError(message=”, , schema_id, violations=None, quarantine_count=0, sample_violations=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

A DataFrame failed schema validation. Carries the full violation list (capped at 10,000 — surplus written to file via §Q file-path mode by the SDK) and a small inline sample for MCP wire serialization (≤10 entries).

  • Parameters:
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.SourceMismatchError(message=”, , schema_source, data_source, role=None, catalog_warning=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.SourceMismatchError(message=”, , schema_source, data_source, role=None, catalog_warning=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

The data’s source does not match the schema’s registered source, and the caller did not opt out via source_drift_reason. role (if set) identifies which leg of a pull_pairs request mismatched and uses the canonical long form: "observations" / "forecasts" / "settlement".

  • Parameters:
    • message (str)
    • schema_source (str)
    • data_source (str)
    • role (str | None)
    • catalog_warning (str | None)
    • source (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Canonical role-name vocabulary (design.md §R).

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.SourceUnavailableError(message=”, , source=None, http_status=None, retryable=False, retry_after_s=None, underlying=”, url=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.SourceUnavailableError(message=”, , source=None, http_status=None, retryable=False, retry_after_s=None, underlying=”, url=None, request_id=None, error_code=None)”

Bases: MostlyrightError

A source (HTTP endpoint, vendored parser, etc.) returned an error or was otherwise unreachable. Carries enough metadata for callers to decide whether to retry and after how long.

  • Parameters:
    • message (str)
    • source (str | None)
    • http_status (int | None)
    • retryable (bool)
    • retry_after_s (float | None)
    • underlying (str)
    • url (str | None)
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.StationOutOfGridError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.StationOutOfGridError(message=”, , error_code=None, source=None, request_id=None)”

Bases: SatelliteError

Station projection lands outside the product grid.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.StormNotFoundError(message=”, , query=”, active_storms=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.StormNotFoundError(message=”, , query=”, active_storms=None, request_id=None, error_code=None)”

Bases: NWPError

A HAFS storm query (id or name) doesn’t match any active storm.

Carries the query and the list of currently-active storm IDs so callers can present a useful error. Historical HAFS access requires passing the canonical storm_id directly (Storms() only knows currently-active storms).

  • Parameters:
    • message (str)
    • query (str)
    • active_storms (list [str ])
    • request_id (str | None)
    • error_code (str)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.TemporalDriftError(message=”, , schema_id, asserted_range, violating_rows, sample_violations=None, source=None, request_id=None, error_code=None)

Section titled “exception mostlyright.core.exceptions.TemporalDriftError(message=”, , schema_id, asserted_range, violating_rows, sample_violations=None, source=None, request_id=None, error_code=None)”

Bases: MostlyrightError

Raised by the reproducibility audit (design.md §P) when one or more rows have retrieved_at outside the asserted range AND fall within the volatile window of now. Indicates the source materially re-amended historical rows since the schema’s registered capture.

  • Parameters:
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.

exception mostlyright.core.exceptions.UnitsContractError(message=”, , error_code=None, source=None, request_id=None)

Section titled “exception mostlyright.core.exceptions.UnitsContractError(message=”, , error_code=None, source=None, request_id=None)”

Bases: GOESDataCorruptError

NetCDF variable units attribute does not match the registry.

Subclass of GOESDataCorruptError (preserving the 2i hierarchy). Per the annotate-never-drop rule, the per-variable units mismatch in _extract_from_dataset is RECORDED as a qc_status="suspect" row and the scan continues — this class stays importable for any genuinely unrecoverable case, but the per-variable mismatch no longer aborts.

  • Parameters:
    • message (str)
    • error_code (str)
    • source (str | None)
    • request_id (str | None)
  • Return type: None

Subclass override — the stable string enum surfaced via error_code.