Skip to Content

Errors

Every failure mode has its own type, so a caller can tell a reference mismatch from a naming mismatch without reading the message. That is what makes the planned automatic fixes possible.

CheckError

class CheckError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

A pipeline will not work, found before anything ran.

Attributes

AttributeDescription
stepThe step the problem was found in. None for the one error that a step body can raise while running rather than a check raise before anything runs — a ReferenceFrameError from lg.hivdb.interpret called outside a pipeline, which has no step to name.
dimensionThe name of the dimension involved, where one is. None for a StepTypeError, which blames no dimension.
scopeWhat distinguishes that step from the others of the same name, as a (kind, value) pair — ("sample", "SRR32217714") under per-sample fan-out. None for a step that stands for no single sample, such as one that spans a whole cohort. Collecting these is how you ask which samples a problem affects: affected = {e.scope[1] for e in pipe.errors() if e.scope}
errorsEvery problem found in the same pass, this one included. Checking reports all of them at once rather than one per run, because fixing errors one per overnight run is the problem Ligase exists to remove.

DimensionError

class DimensionError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

Two inputs to a step disagree about a dimension.

The message names the step, both conflicting values, where each value came from, and asks a leading question. The provenance is the part that makes it actionable: knowing two references disagree sends you hunting, while knowing one came from a BAM @SQ header and the other from the FASTA you passed tells you what to change.

ContigNamingError

class ContigNamingError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

The same contigs under different names, such as chr1 against 1.

Distinct from a plain DimensionError because the fix is distinct: a renaming step, not a different reference. Still a DimensionError, so code that wants to catch any dimension problem can.

ContigOrderError

class ContigOrderError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

The same contigs in a different order.

htslib matches contigs by name, so bcftools does not mind. GATK requires sequence dictionaries in matching order and will reject this.

ReferenceFrameError

class ReferenceFrameError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

A reference is not numbered along the frame a step reads positions in.

A step whose own coordinates are fixed — lg.hivdb.interpret holds the HIV-1 gene windows as positions in HXB2 K03455 — cannot read them against a reference numbered along something else. A pol-relative reference is the case that matters: it is a slice of K03455 starting at 2085, so every position in it is 2084 lower, and reading it anyway puts integrase under the window named protease.

Distinct from a plain DimensionError because the fix is distinct. The reference is not the wrong file; it is the right sequence in the wrong place, and the fix is to put it back — pad a pol-relative reference with "N" * 2084 and declare frame=("K03455", 1) where you load it.

Raised by check() before anything runs, where the reference’s declared frame is known. Also raised by lg.hivdb.interpret itself, for a caller who reached the engine without a pipeline; that one names no step.

UndeclaredDimensionError

class UndeclaredDimensionError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

A dimension some step requires is unknown and must be declared.

Raised only because a step actually joins on it: an unknown dimension nothing downstream requires is allowed to stay unknown. The message names the data that has to declare it and the route by which it reaches the step that needs it, which for a value propagated through the graph are two different places.

StepTypeError

class StepTypeError( message: 'str', step: 'str | None' = None, dimension: 'str | None' = None, scope: 'tuple[str, str] | None' = None, ) -> 'None'

A step was handed a kind of data it does not declare.

Not a DimensionError: nothing disagrees about the data, the pipeline is simply wired up wrong. Reported instead of that step’s dimension errors rather than alongside them, because comparing the dimensions of bindings the step never declared would describe a pipeline you did not write.

StepDefinitionError

A decorated function cannot be used as a step.

Raised by @lg.step as the module is imported, not at check time: a missing annotation is a mistake in the pipeline’s source, and the sooner it is said the less there is to read. A TypeError, because that is what a badly typed definition is.

LoadError

A file could not be read or did not parse as the expected format.

RemoteError

A remote input could not be fetched, or is not what its digest says.

RunError

class RunError(report: 'RunReport') -> 'None'

A step failed.

Attributes

AttributeDescription
reportThe whole run, including everything that did succeed — which for a cohort is usually most of it.
failuresThe steps that failed, as a shortcut.

StepFailure

class StepFailure( step: 'str', sample: 'str | None', message: 'str', node: 'int', ) -> None

One step that did not produce anything.

A step whose input failed is in neither list: one cause, one failure.

Attributes

AttributeDescription
stepThe step’s name.
sampleThe sample it was for, where it stands for one.
messageWhat went wrong, in the tool’s own words where there are any.
nodeWhich node of the graph it was.

InputCheck

class InputCheck( step: 'str', param: 'str', path: 'str', presence: 'str', ) -> None

One input file, as a bundle recorded it and as it is here.

Attributes

AttributeDescription
stepThe step it fed.
paramThe parameter it filled.
pathWhere the bundle said it was.
presencesame, changed or absent, by content rather than by name — which is the only way to tell the file a bundle was built from apart from a different file with the same name.

ResultCheck

class ResultCheck( step: 'str', scope: 'str | None', verdict: 'str', expected: 'str', found: 'str | None', same_key: 'bool', ) -> None

One result, as a bundle recorded it and as this machine produced it.

Attributes

AttributeDescription
stepThe step’s name.
scopeWhat tells this node apart, where anything does.
verdictidentical, reproduced, differs or missing.
expectedThe canonical hash the bundle recorded.
foundThe canonical hash produced here, or None where this pipeline produced nothing for it.
same_keyWhether the cache key matched too. False with a verdict of reproduced means something in the environment moved and the result did not, which is the interesting outcome.

ResultCheck.reproduced

reproduced: bool # property

Whether the result came out the same, by either route.

Last updated on