Errors and what to do about them

Every exception the library raises inherits from SignalDatasetError, so one except clause catches all of them:

import signal_dataset as sds

try:
    dataset = sds.open("captures.sds")
except sds.SignalDatasetError as error:
    ...

Each also inherits from the built-in exception that best describes it, so existing handlers keep working. Catching ValueError still catches a validation failure.

Exception

Also a

Raised when

ValidationError

ValueError

A record you built is not valid

PublicationCollisionError

FileExistsError

The publication target already exists

CorruptDatasetError

ValueError

A stored document or shard is inconsistent

StorageError

OSError

The storage backend failed

ValidationError

Your input is wrong, and nothing was written. This is the error you get while building records: an unsupported dtype, an axis length that disagrees with the array it describes, metadata that is not JSON-compatible, or a resource policy exceeded.

Validation runs before any encoding, so a ValidationError never leaves partial state behind. Fix the record and retry.

Two common cases worth naming. complex128 is not a supported dtype: convert to complex64 explicitly, so the precision loss is yours rather than the library’s. Object arrays are not supported either: put strings and heterogeneous values in JSON metadata instead.

PublicationCollisionError

This is usually expected behaviour rather than a fault. Publication is create-only, so this error is how the format refuses to overwrite something.

You will see it when:

  • You publish a different snapshot_id or dataset_id into an existing root. A root holds exactly one snapshot. Publish to a different root.

  • Two publishers raced for the same annotation set name. One won. The message reads annotation set name already exists. Republish under a different publication_id.

  • An annotation catalog update exhausted its retries under contention, which reads annotation catalog update retry limit exceeded. Retry, or reduce concurrent publishers.

Note the case that does not raise: re-running an identical publication succeeds, because every write is create-only and resumes on an identical object. That is what makes an interrupted publication safe to repeat. See running it a second time.

CorruptDatasetError

A stored control document or shard does not describe a dataset this reader can trust. The library raises this rather than returning data it cannot vouch for.

The realistic causes, in rough order of likelihood:

  • The reader is too old for the dataset. A dataset published by a newer library can require a newer reader. The message names the version you need, for example 0.3.0 or newer. Upgrade the reader. This is the one case that is not damage.

  • Something outside the library wrote into the root. The format assumes it owns everything under a root. A tool that copied objects without their manifests, or a partial rsync, produces exactly this.

  • A truncated or half-written upload. Publication compares each shard’s byte size, so a truncated object is normally caught at publication rather than at read time.

There is no repair tool, and by design there is nothing to repair in place: the library never deletes or modifies an object. Republish the affected snapshot under a new snapshot_id, or a new root. If you cannot, the manifest is the place to start reading, since it names precisely which objects the snapshot expects.

StorageError

The backend itself failed: a network error, a permission problem, an unexpected response. The cause is attached, so raise ... from chains give you the vendor exception underneath.

Most storage errors are transient. Publication and shard writing accept a retry= argument for exactly this, and retrying is safe because every write is create-only and resumes on an identical object.

If it is not transient, check credentials and bucket permissions first. A StorageError on the very first request of a run is nearly always configuration rather than infrastructure.