Error Reference¶
Every exception Ubunye raises, for people who catch errors in Python. If you have an error message and want the fix, start at Troubleshooting instead.
Every user-facing error inherits from UbunyeError and the standard Python
type it replaces, so existing except ValueError or except KeyError catches
keep working.
Catching errors¶
import ubunye
from ubunye import UbunyeError
try:
ubunye.run_task(task_dir="pipelines/fraud/ingestion/claim_etl")
except UbunyeError as e:
print(e) # formatted message with context + hint
print(e.context) # dict of relevant facts
print(e.hint) # suggested fix (or None)
Narrow catches still work via dual inheritance:
except FileNotFoundError: # catches TaskNotFoundError, RegistryNotFoundError
except KeyError: # catches ReaderNotFoundError, WriterNotFoundError, SecretError, FeatureContractError
except ValueError: # catches ConfigError, RegistryError subtypes, ExpectationError
except RuntimeError: # catches SparkSessionError, ModelNotFittedError, DeployError, LLMError, RunLeaseHeld
Exception hierarchy¶
UbunyeError(Exception)
├── ConfigError(UbunyeError, ValueError)
│ ├── ConfigFieldError unknown config fields, with typo suggestions
│ ├── ConfigTemplateError undefined Jinja variables, unset env variables
│ └── ConfigProfileError a profile name the config does not define
├── TaskNotFoundError(UbunyeError, FileNotFoundError)
├── TaskClassMissingError(UbunyeError, RuntimeError)
├── PluginNotFoundError(UbunyeError, KeyError)
│ ├── ReaderNotFoundError
│ ├── WriterNotFoundError
│ ├── TransformNotFoundError
│ ├── MonitorNotFoundError
│ ├── BackendNotFoundError no backend under that name, or it failed to load
│ └── RegistryBackendNotFoundError no registry backend under that name, or it failed to load
├── SourceReadError(UbunyeError, IOError)
├── SinkWriteError(UbunyeError, IOError)
├── TransformOutputError(UbunyeError, TypeError)
├── SecretError(UbunyeError, KeyError) a secret:// reference cannot be read
├── LLMError(UbunyeError, RuntimeError) a model call fails or cannot be made
│ └── LLMBudgetError a call refused before sending: it could pass a limit
├── ExpectationError(UbunyeError, ValueError) an output breaks a `fail` expectation; nothing written
├── BackendCapabilityError(UbunyeError, ValueError) the task needs something the backend cannot do
├── SparkSessionError(UbunyeError, RuntimeError)
├── ModelLoadError(UbunyeError, ImportError)
├── ModelNotFittedError(UbunyeError, RuntimeError)
├── FeatureContractError(UbunyeError, KeyError) at predict, the frame lacks a feature the model declared
├── RegistryError(UbunyeError, ValueError)
│ ├── VersionExistsError
│ ├── VersionNotFoundError
│ └── PromotionBlockedError
├── RegistryNotFoundError(UbunyeError, FileNotFoundError)
├── LineageRecordNotFoundError(UbunyeError, FileNotFoundError)
├── RunLeaseHeld(UbunyeError, RuntimeError) another live run holds this task and batch
│ └── BatchFinished a finished run already appended this batch; --rerun replaces it
├── RunLeaseLost(UbunyeError, RuntimeError) this run's lease was taken over; it stops
├── UpstreamNotReady(UbunyeError, RuntimeError) a task in CONFIG.requires has not succeeded for this batch
└── DeployError(UbunyeError, RuntimeError)
├── AuthNotFoundError Databricks credentials are missing
├── AuthInvalidError Databricks credentials are rejected
├── TargetNotFoundError the deploy target is not in targets.yaml
├── WorkspaceUploadError uploading files to the workspace failed
└── BundleDeployError creating or updating the job failed
SecretError and LLMError never carry the secret or the key.
RunLeaseHeld, BatchFinished and RunLeaseLost are explained in
Safe reruns; FeatureContractError in
ADR 012.
Example error output¶
Missing transformations.py
TaskNotFoundError: Missing transformations.py at pipelines/demo/etl/hello_world/transformations.py.
Task dir: pipelines/demo/etl/hello_world
Expected file: pipelines/demo/etl/hello_world/transformations.py
Hint: Run 'ubunye init' to scaffold a new task, or check the directory path.
Unknown reader format
ReaderNotFoundError: Reader plugin 'hve' not found.
Format: hve
Input: source
Installed: ['binary', 'delta', 'hive', 'jdbc', 'rest_api', 's3', 'unity']
Hint: Check the 'format' field in CONFIG.inputs.source. Installed reader plugins: binary, delta, hive, jdbc, rest_api, s3, unity
Invalid profile
ConfigProfileError: Profile 'staging' not found.
Profile: staging
Available: ['DEV', 'PROD']
Hint: This config's profiles are: DEV, PROD. Names match exactly, case included. With no -m, run, validate, plan and doctor use DEV.
Missing env variable (Jinja)
ConfigTemplateError: Template resolution failed for pipelines/demo/etl/hello_world/config.yaml:
Environment variable 'DB_PASS' is not set (referenced in '{{ env.DB_PASS }}'). Set it in your environment or use {{ env.DB_PASS | default('fallback') }}.
An undefined variable that is not under env gives Undefined variable 'name' in config value ...,
with the list of variables that are available.
Importing exceptions¶
# Broadest catch
from ubunye import UbunyeError
# By category
from ubunye.core.errors import (
ConfigError,
SourceReadError,
SinkWriteError,
TaskNotFoundError,
ReaderNotFoundError,
)
# Also available from ubunye.core (all but SecretError, LLMError,
# LLMBudgetError and ExpectationError, which only ubunye.core.errors has)
from ubunye.core import TaskNotFoundError
# Elsewhere
from ubunye.core.runs import RunLeaseHeld, BatchFinished, RunLeaseLost
from ubunye.lineage.upstream import UpstreamNotReady
from ubunye.models.backends import RegistryBackendNotFoundError