Home / guides / error-handling
Error Handling
All exceptions raised by Icechunk derive from IcechunkError. Subclasses group failures into categories by what a handler would do about them, and every instance carries a stable machine-readable kind code identifying the precise failure.
The exception tree
IcechunkError
├── ConflictError
│ └── RebaseFailedError
├── NotFoundError (also a KeyError)
│ ├── NodeNotFoundError
│ ├── SnapshotNotFoundError
│ ├── RefNotFoundError
│ └── RepositoryNotFoundError
├── AlreadyExistsError
├── ReadOnlyError
├── InvalidInputError (also a ValueError)
├── SessionStateError
├── StorageError
├── FormatError
└── InternalError
| Exception | Raised when |
ConflictError | A concurrent writer got there first: commit conflicts, branch update conflicts |
RebaseFailedError | A rebase could not resolve all conflicts; carries snapshot and conflicts |
NotFoundError | Something that was asked for does not exist |
NodeNotFoundError | No group, array, or chunk at the given path |
SnapshotNotFoundError | No snapshot with the given id (or at the given time) |
RefNotFoundError | No branch or tag with the given name |
RepositoryNotFoundError | No Icechunk repository at the given storage location |
AlreadyExistsError | Something being created already exists (node, branch, tag...) |
ReadOnlyError | A write through a read-only session, store, or repository |
InvalidInputError | An argument, key, index, or metadata value is invalid |
SessionStateError | The operation is not allowed in the current session or repository state |
StorageError | The object store or local storage failed, or is misconfigured; often transient |
FormatError | On-disk data could not be read or written: corruption, unsupported spec version |
InternalError | An unexpected internal error; likely a bug worth reporting |
Catching exceptions
Catch a category when your handler treats every failure in it the same way:
import icechunk
try:
session.commit("append forecast")
except icechunk.ConflictError:
session.rebase(icechunk.ConflictDetector())
session.commit("append forecast")
try:
session = repo.readonly_session(tag=name)
except icechunk.NotFoundError:
session = repo.readonly_session(branch="main")
Catch IcechunkError when you only want to know "was this Icechunk?":
try:
ingest(repo)
except icechunk.IcechunkError as e:
log.error("ingest failed", kind=e.kind, message=str(e))
raise
Dispatching on kind
When a category is too coarse, match the kind attribute — an ErrorKind code that pins down the exact failure without needing one class per failure:
try:
repo.create_tag(name, snapshot_id=snapshot_id)
except icechunk.AlreadyExistsError as e:
if e.kind == icechunk.ErrorKind.TAG_PREVIOUSLY_DELETED:
raise RuntimeError(f"tag {name} was deleted and cannot be recreated") from e
pass # already tagged: fine, idempotent
Codes are append-only: new ones may appear in any release, but existing ones are never renamed or removed, so it is safe to persist and compare them.
Compatibility with builtin exceptions
Two categories also derive from the builtin exception you'd expect, so pre-existing handlers keep working:
NotFoundError is a KeyError InvalidInputError is a ValueError
try:
session = repo.readonly_session(branch="nope")
except KeyError: # RefNotFoundError is a KeyError
...
The KeyError is most relevant for zarr, which internally checks for it when handling missing keys. ValueError is kept for preserving compatibility with earlier Icechunk releases, which raised it for invalid input.
What an error looks like
str(e) (also available as e.message) is the chain of causes followed by the operation context — which Icechunk operations were running, with their arguments:
>>> try:
... repo.readonly_session(branch="nope")
... except icechunk.IcechunkError as e:
... print(e)
ref not found `nope`
context:
0: icechunk::repository::lookup_branch_v2
with branch="nope" repo_info=Some(RepoInfo { ... })
at icechunk/src/repository.rs:1240
1: icechunk::repository::resolve_ref_version_v2
with version=BranchTipRef("nope")
at icechunk/src/repository.rs:1690
2: icechunk::repository::resolve_version_v2
with version=BranchTipRef("nope")
at icechunk/src/repository.rs:1772
3: icechunk::repository::readonly_session
with version=BranchTipRef("nope")
at icechunk/src/repository.rs:1925
repr(e) identifies the class and kind:
>>> repr(e)
'icechunk.RefNotFoundError(message="ref not found `nope`...", kind="ref-not-found")'
Uncaught, the traceback shows the exception as usual, plus the full diagnostic report attached as a PEP 678 note:
Traceback (most recent call last):
File "ingest.py", line 4, in <module>
repo.readonly_session(branch="nope")
File ".../icechunk/repository.py", line 1534, in readonly_session
self._repository.readonly_session(
icechunk.RefNotFoundError: ref not found `nope`
context:
0: icechunk::repository::lookup_branch_v2
...
x ref not found `nope`
|
| context:
| 0: icechunk::repository::lookup_branch_v2
| ...
`-> ref not found `nope`
All error kinds
icechunk.ErrorKind
Bases: StrEnum
Stable machine-readable codes for the kind attribute of IcechunkError.
Codes are append-only: new ones may appear in any release, but existing ones are not renamed or removed, since user code matches on them (if e.kind == ErrorKind.CHUNK_NOT_FOUND:) and would silently miss a renamed code.
Members are written out literally (rather than generated from the Rust side) so type checkers can see them; test_error_kind_enum_in_sync_with_rust keeps them in sync with the codes Rust actually raises.
ANCESTOR_NODE_NOT_FOUND class-attribute instance-attribute
ANCESTOR_NODE_NOT_FOUND = 'ancestor-node-not-found'
BAD_KEY_PREFIX class-attribute instance-attribute
BAD_KEY_PREFIX = 'bad-key-prefix'
BAD_METADATA = 'bad-metadata'
BAD_PREFIX class-attribute instance-attribute
BAD_PREFIX = 'bad-prefix'
BAD_REDIRECT class-attribute instance-attribute
BAD_REDIRECT = 'bad-redirect'
BAD_SNAPSHOT_CHAIN_FOR_DIFF class-attribute instance-attribute
BAD_SNAPSHOT_CHAIN_FOR_DIFF = 'bad-snapshot-chain-for-diff'
BRANCH_ALREADY_EXISTS class-attribute instance-attribute
BRANCH_ALREADY_EXISTS = 'branch-already-exists'
BRANCH_NOT_FOUND class-attribute instance-attribute
BRANCH_NOT_FOUND = 'branch-not-found'
BRANCH_UPDATE_CONFLICT class-attribute instance-attribute
BRANCH_UPDATE_CONFLICT = 'branch-update-conflict'
CANNOT_DELETE_MAIN class-attribute instance-attribute
CANNOT_DELETE_MAIN = 'cannot-delete-main'
CANNOT_FORK_READ_ONLY_SESSION class-attribute instance-attribute
CANNOT_FORK_READ_ONLY_SESSION = (
"cannot-fork-read-only-session"
)
CANNOT_PARSE_URL class-attribute instance-attribute
CANNOT_PARSE_URL = 'cannot-parse-url'
CHUNK_NOT_FOUND class-attribute instance-attribute
CHUNK_NOT_FOUND = 'chunk-not-found'
COMMIT_CONFLICT class-attribute instance-attribute
COMMIT_CONFLICT = 'commit-conflict'
COMMIT_NOT_ALLOWED class-attribute instance-attribute
COMMIT_NOT_ALLOWED = 'commit-not-allowed'
CONCURRENCY class-attribute instance-attribute
CONCURRENCY = 'concurrency'
CONFIG_DESERIALIZATION class-attribute instance-attribute
CONFIG_DESERIALIZATION = 'config-deserialization'
CONFIG_UPDATED class-attribute instance-attribute
CONFIG_UPDATED = 'config-updated'
CONFLICTING_PATH_NOT_FOUND class-attribute instance-attribute
CONFLICTING_PATH_NOT_FOUND = 'conflicting-path-not-found'
DESERIALIZATION class-attribute instance-attribute
DESERIALIZATION = 'deserialization'
DUPLICATE_SNAPSHOT_ID class-attribute instance-attribute
DUPLICATE_SNAPSHOT_ID = 'duplicate-snapshot-id'
EMPTY_PREFIX_CREATION class-attribute instance-attribute
EMPTY_PREFIX_CREATION = 'empty-prefix-creation'
FEATURE_FLAG_DISABLED class-attribute instance-attribute
FEATURE_FLAG_DISABLED = 'feature-flag-disabled'
FLUSH class-attribute instance-attribute
INCONSISTENT_MANIFESTS class-attribute instance-attribute
INCONSISTENT_MANIFESTS = 'inconsistent-manifests'
INVALID_ARRAY_METADATA = 'invalid-array-metadata'
INVALID_BYTE_RANGE class-attribute instance-attribute
INVALID_BYTE_RANGE = 'invalid-byte-range'
INVALID_CHUNK_INDEX class-attribute instance-attribute
INVALID_CHUNK_INDEX = 'invalid-chunk-index'
INVALID_COMMIT_CONFIGURATION class-attribute instance-attribute
INVALID_COMMIT_CONFIGURATION = (
"invalid-commit-configuration"
)
INVALID_CREDENTIALS class-attribute instance-attribute
INVALID_CREDENTIALS = 'invalid-credentials'
INVALID_FEATURE_FLAG class-attribute instance-attribute
INVALID_FEATURE_FLAG = 'invalid-feature-flag'
INVALID_FILE_FORMAT = 'invalid-file-format'
INVALID_KEY class-attribute instance-attribute
INVALID_KEY = 'invalid-key'
INVALID_MANIFEST_SPLIT_INDEX class-attribute instance-attribute
INVALID_MANIFEST_SPLIT_INDEX = (
"invalid-manifest-split-index"
)
INVALID_OBJECT_SIZE class-attribute instance-attribute
INVALID_OBJECT_SIZE = 'invalid-object-size'
INVALID_PATH class-attribute instance-attribute
INVALID_PATH = 'invalid-path'
INVALID_REF_NAME class-attribute instance-attribute
INVALID_REF_NAME = 'invalid-ref-name'
INVALID_REF_TYPE class-attribute instance-attribute
INVALID_REF_TYPE = 'invalid-ref-type'
INVALID_REPOSITORY_MIGRATION class-attribute instance-attribute
INVALID_REPOSITORY_MIGRATION = (
"invalid-repository-migration"
)
INVALID_SNAPSHOT_ID class-attribute instance-attribute
INVALID_SNAPSHOT_ID = 'invalid-snapshot-id'
INVALID_VIRTUAL_REF class-attribute instance-attribute
INVALID_VIRTUAL_REF = 'invalid-virtual-ref'
IO class-attribute instance-attribute
KEY_NOT_FOUND class-attribute instance-attribute
KEY_NOT_FOUND = 'key-not-found'
MANIFEST_INFO_NOT_FOUND class-attribute instance-attribute
MANIFEST_INFO_NOT_FOUND = 'manifest-info-not-found'
MERGE_FAILED class-attribute instance-attribute
MERGE_FAILED = 'merge-failed'
MERGE_NOT_ALLOWED class-attribute instance-attribute
MERGE_NOT_ALLOWED = 'merge-not-allowed'
MOVE_DESTINATION_PARENT_MISSING class-attribute instance-attribute
MOVE_DESTINATION_PARENT_MISSING = (
"move-destination-parent-missing"
)
MOVE_DESTINATION_PARENT_NOT_GROUP class-attribute instance-attribute
MOVE_DESTINATION_PARENT_NOT_GROUP = (
"move-destination-parent-not-group"
)
MOVE_INTO_SELF_OR_DESCENDANT class-attribute instance-attribute
MOVE_INTO_SELF_OR_DESCENDANT = (
"move-into-self-or-descendant"
)
MOVE_WONT_OVERWRITE class-attribute instance-attribute
MOVE_WONT_OVERWRITE = 'move-wont-overwrite'
NODE_ALREADY_EXISTS class-attribute instance-attribute
NODE_ALREADY_EXISTS = 'node-already-exists'
NODE_NOT_FOUND class-attribute instance-attribute
NODE_NOT_FOUND = 'node-not-found'
NON_REARRANGE_SESSION class-attribute instance-attribute
NON_REARRANGE_SESSION = 'non-rearrange-session'
NOT_ALLOWED class-attribute instance-attribute
NOT_ALLOWED = 'not-allowed'
NOT_AN_ARRAY class-attribute instance-attribute
NOT_AN_ARRAY = 'not-an-array'
NOT_A_GROUP class-attribute instance-attribute
NOT_A_GROUP = 'not-a-group'
NOT_ON_BRANCH class-attribute instance-attribute
NOT_ON_BRANCH = 'not-on-branch'
NO_AMEND_FOR_INITIAL_COMMIT class-attribute instance-attribute
NO_AMEND_FOR_INITIAL_COMMIT = 'no-amend-for-initial-commit'
NO_CHANGES_TO_COMMIT class-attribute instance-attribute
NO_CHANGES_TO_COMMIT = 'no-changes-to-commit'
NO_CONTAINER_FOR_VIRTUAL_CHUNK class-attribute instance-attribute
NO_CONTAINER_FOR_VIRTUAL_CHUNK = (
"no-container-for-virtual-chunk"
)
NO_SNAPSHOT class-attribute instance-attribute
NO_SNAPSHOT = 'no-snapshot'
NO_SNAPSHOT_AT_TIME class-attribute instance-attribute
NO_SNAPSHOT_AT_TIME = 'no-snapshot-at-time'
OBJECT_NOT_FOUND class-attribute instance-attribute
OBJECT_NOT_FOUND = 'object-not-found'
OBJECT_STORE class-attribute instance-attribute
OBJECT_STORE = 'object-store'
PARENT_DIRECTORY_NOT_CLEAN class-attribute instance-attribute
PARENT_DIRECTORY_NOT_CLEAN = 'parent-directory-not-clean'
PARTIAL_VALUES_PANIC class-attribute instance-attribute
PARTIAL_VALUES_PANIC = 'partial-values-panic'
PICKLE class-attribute instance-attribute
POISON_LOCK class-attribute instance-attribute
POISON_LOCK = 'poison-lock'
READ_ONLY_REPOSITORY class-attribute instance-attribute
READ_ONLY_REPOSITORY = 'read-only-repository'
READ_ONLY_SESSION class-attribute instance-attribute
READ_ONLY_SESSION = 'read-only-session'
READ_ONLY_STORAGE class-attribute instance-attribute
READ_ONLY_STORAGE = 'read-only-storage'
READ_ONLY_STORE class-attribute instance-attribute
READ_ONLY_STORE = 'read-only-store'
REARRANGE_SESSION_ONLY class-attribute instance-attribute
REARRANGE_SESSION_ONLY = 'rearrange-session-only'
REBASE_FAILED class-attribute instance-attribute
REBASE_FAILED = 'rebase-failed'
REBASE_TX_LOG_PRUNED class-attribute instance-attribute
REBASE_TX_LOG_PRUNED = 'rebase-tx-log-pruned'
REF_NOT_FOUND class-attribute instance-attribute
REF_NOT_FOUND = 'ref-not-found'
REPOSITORY_NOT_FOUND class-attribute instance-attribute
REPOSITORY_NOT_FOUND = 'repository-not-found'
REPO_INFO_UPDATED class-attribute instance-attribute
REPO_INFO_UPDATED = 'repo-info-updated'
SEMAPHORE_ACQUIRE class-attribute instance-attribute
SEMAPHORE_ACQUIRE = 'semaphore-acquire'
SERIALIZATION class-attribute instance-attribute
SERIALIZATION = 'serialization'
SNAPSHOT_NOT_FOUND class-attribute instance-attribute
SNAPSHOT_NOT_FOUND = 'snapshot-not-found'
SNAPSHOT_TIMESTAMP class-attribute instance-attribute
SNAPSHOT_TIMESTAMP = 'snapshot-timestamp'
STORAGE_CONFIG class-attribute instance-attribute
STORAGE_CONFIG = 'storage-config'
STORAGE_OTHER class-attribute instance-attribute
STORAGE_OTHER = 'storage-other'
TAG_ALREADY_EXISTS class-attribute instance-attribute
TAG_ALREADY_EXISTS = 'tag-already-exists'
TAG_ERROR class-attribute instance-attribute
TAG_NOT_FOUND class-attribute instance-attribute
TAG_NOT_FOUND = 'tag-not-found'
TAG_PREVIOUSLY_DELETED class-attribute instance-attribute
TAG_PREVIOUSLY_DELETED = 'tag-previously-deleted'
UNAUTHORIZED_VIRTUAL_CHUNK_CONTAINER class-attribute instance-attribute
UNAUTHORIZED_VIRTUAL_CHUNK_CONTAINER = (
"unauthorized-virtual-chunk-container"
)
UNCOMMITTED_CHANGES class-attribute instance-attribute
UNCOMMITTED_CHANGES = 'uncommitted-changes'
UNIMPLEMENTED class-attribute instance-attribute
UNIMPLEMENTED = 'unimplemented'
UNKNOWN class-attribute instance-attribute
UNSUPPORTED_OPERATION_FOR_VERSION class-attribute instance-attribute
UNSUPPORTED_OPERATION_FOR_VERSION = (
"unsupported-operation-for-version"
)
UNSUPPORTED_SPEC_VERSION class-attribute instance-attribute
UNSUPPORTED_SPEC_VERSION = 'unsupported-spec-version'
UPDATE_ATTEMPTS_EXHAUSTED class-attribute instance-attribute
UPDATE_ATTEMPTS_EXHAUSTED = 'update-attempts-exhausted'
VIRTUAL_CHUNK_FETCH class-attribute instance-attribute
VIRTUAL_CHUNK_FETCH = 'virtual-chunk-fetch'
VIRTUAL_CHUNK_MODIFIED class-attribute instance-attribute
VIRTUAL_CHUNK_MODIFIED = 'virtual-chunk-modified'