pub enum PackchainError {
Show 28 variants
UnsupportedSchemaVersion {
found: u32,
expected: u32,
},
InvalidSha {
found: String,
},
ParseJson(Error),
InvalidPath {
bytes: Vec<u8>,
},
Git(GitError),
ShallowPushRejected,
ChainAbsent {
ref_name: String,
},
PackMissing {
key: String,
},
BaselineMissing {
key: String,
},
PackTrailer(String),
PackBuild(String),
PackIndexWrite(Box<Error>),
Store(ObjectStoreError),
Io(Error),
WrongEngine {
found: StorageEngine,
},
PathIndexAbsent {
ref_name: String,
},
PathNotFound {
ref_name: String,
path: String,
},
MalformedPath {
path: String,
reason: &'static str,
},
PathNotABlob {
path: String,
},
BlobNotInChain {
sha: String,
path: String,
},
MalformedPackEntry {
offset: u64,
reason: String,
},
Decompress {
offset: u64,
},
DeltaTooDeep {
max: u32,
},
MalformedDelta {
reason: &'static str,
},
InvalidRefName {
name: String,
},
TreeCycle {
oid: String,
},
TransientChainPathIndexMismatch {
ref_name: String,
chain_tip: String,
path_index_tip: String,
},
ConcurrentGcRetriesExhausted {
last_missing_key: String,
attempts: u32,
},
}Expand description
Errors surfaced by the packchain engine. pub because the
crate::protocol::push::PushError::Packchain variant — which is
public — wraps it; making this pub(crate) would leak a private
type through a public API. The packchain engine itself stays
pub(crate) (see pub(crate) mod push etc.); only gc and read
are pub for rustdoc / direct-access reachability.
Variants§
UnsupportedSchemaVersion
On-bucket schema declares a version this build cannot read. The
expected field is the version this build writes; found is
the value parsed from the JSON. Lets a future v=2 reader refuse
v=1 clients (and vice versa) cleanly.
InvalidSha
A field that should hold a 40-lowercase-hex SHA contained
something else. Validation runs on every [schema::Sha40]
deserialise so a malformed chain.json or path-index.json
cannot leak past the parser into the rest of the engine.
Fields
ParseJson(Error)
Underlying serde_json parse error (malformed JSON, missing
fields, type mismatches that aren’t caught by [schema::Sha40]’s
validator).
InvalidPath
Tree entry filename was not valid UTF-8. Git allows arbitrary
bytes in tree entry names, but the on-bucket JSON layer cannot
represent non-UTF-8 keys without a lossy encoding (banned by
.claude/rules/rust.md). Carries the offending bytes verbatim
for diagnostics.
Git(GitError)
Underlying gix / git error from tree-walking, ref lookups, or other git-side operations.
ShallowPushRejected
Local repository is shallow (a .git/shallow file exists) and
the rev-walk from the local tip crosses a shallow boundary, so
a complete pack cannot be produced. Pushing from a shallow
clone would leave the server with permanently incomplete
history; better to refuse loudly than to corrupt the remote.
ChainAbsent
chain.json is missing for the requested ref. Either the
branch was never pushed under the packchain engine or it was
deleted server-side. Distinct from
Self::Store(NotFound) so the wire-line is explicit
about which artefact is missing.
PackMissing
chain.json references a pack that is not present on the
bucket. Pinning this as a typed error so doctor can flag it
specifically rather than the operator having to disambiguate a
generic NotFound from a transient failure. Issue #64 calls
this out as a regression case to surface loudly rather than
silently zero-byte-fetch.
BaselineMissing
Baseline bundle (the <full_at>.bundle artefact) is missing.
Surfaces during a clone where the chain walk reached the root
segment but the baseline that should be alongside it is gone.
PackTrailer(String)
Pack content SHA could not be derived (file shorter than the 32-byte minimum PACK header + trailer, or an I/O error reading the trailer).
PackBuild(String)
gix_pack::data::output::count::objects or FromEntriesIter
failed during pack emission.
PackIndexWrite(Box<Error>)
gix_pack::Bundle::write_to_directory failed during the
post-pack .idx derivation pass.
Store(ObjectStoreError)
Underlying object-store transport / auth error.
Io(Error)
Local I/O failure (tempdir, file read, file persist).
WrongEngine
read::read_blob was called against a remote whose resolved
engine is not crate::url::StorageEngine::Packchain. Surfaces
before any artefact lookup so callers see a typed mismatch
instead of a misleading chain.json not-found.
Fields
found: StorageEngineEngine the remote actually resolved to.
PathIndexAbsent
path-index.json is missing for the requested ref. Distinct
from Self::ChainAbsent so an operator sees which artefact is
gone — chain.json being present without path-index indicates a
crashed-mid-push state manage gc will reconcile.
Fields
ref_name: StringThe ref name read::read_blob was asked about.
PathNotFound
Caller passed a path that does not exist in this commit’s tree.
Fields
MalformedPath
Caller passed a malformed path: empty, absolute (/-prefixed),
containing a .. segment, or containing empty segments
(consecutive slashes). These shapes don’t map to git tree
semantics; reject before walking.
Fields
PathNotABlob
Path resolved to a tree node, not a blob — the caller asked for
a directory, not a file. Distinct from Self::PathNotFound so
the caller can distinguish “wrong shape” from “missing”.
BlobNotInChain
Blob SHA recorded in path-index.json was not present in any
pack referenced by chain.json. Indicates a corrupted bucket
(path-index points at a blob the chain doesn’t carry); typed
distinctly so doctor can flag it specifically.
MalformedPackEntry
Pack entry header could not be decoded (truncated bytes, unknown type id, non-canonical size encoding, etc.).
Fields
Decompress
Zlib stream embedded in a pack entry could not be inflated.
DeltaTooDeep
Delta resolution exceeded read::MAX_DELTA_DEPTH. Mirrors
git’s own depth cap — most legitimate chains stay well under it,
so a deep chain is almost certainly a corrupted pack with a
delta cycle.
Fields
max: u32The depth limit (always read::MAX_DELTA_DEPTH).
MalformedDelta
Delta payload could not be applied (truncated instructions, out-of-range copy span, source size mismatch).
InvalidRefName
read_blob was given a ref name that fails gix-validate’s
reference-name rules (empty, control characters, .., etc.).
TreeCycle
Tree closure walk encountered a cycle: a tree references itself directly or transitively via an ancestor on the current descent. Content-addressing makes cycles impossible in a healthy ODB, so this surfaces a corrupted or adversarial repository rather than looping unbounded and exhausting the call stack.
TransientChainPathIndexMismatch
Reader observed chain.json and path-index.json with
mismatched tips — a transient state during the brief window
where a push or compact has committed the new chain.json but
not yet overwritten path-index.json (issue #114). The reader
refuses to resolve a path against an out-of-sync path-index
because the resolved blob SHA may name a different file than
the caller intended; instead it surfaces this typed error so
the caller can retry. Subsequent reads converge once the writer
finishes the path-index PUT.
Fields
ConcurrentGcRetriesExhausted
read::read_blob retried Self::PackMissing failures the
configured number of times and gave up. Each retry reloaded
chain.json and observed that the failing pack key was no
longer referenced — consistent with a concurrent
manage gc sweep deleting compacted-away packs — but a fresh
PackMissing showed up on the new chain anyway, suggesting a
vigorous compact+sweep cycle that kept outpacing the reader.
Distinct from Self::PackMissing so callers can treat it as
“retry the whole read_blob call later” rather than as a
permanent bucket inconsistency (issue #136).
Trait Implementations§
Source§impl Debug for PackchainError
impl Debug for PackchainError
Source§impl Display for PackchainError
impl Display for PackchainError
Source§impl Error for PackchainError
impl Error for PackchainError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<Error> for PackchainError
impl From<Error> for PackchainError
Source§impl From<Error> for PackchainError
impl From<Error> for PackchainError
Source§impl From<Error> for PackchainError
impl From<Error> for PackchainError
Source§impl From<GitError> for PackchainError
impl From<GitError> for PackchainError
Source§impl From<JoinError> for PackchainError
impl From<JoinError> for PackchainError
Source§impl From<ObjectStoreError> for PackchainError
impl From<ObjectStoreError> for PackchainError
Source§fn from(source: ObjectStoreError) -> Self
fn from(source: ObjectStoreError) -> Self
Source§impl From<PackchainError> for FetchError
impl From<PackchainError> for FetchError
Source§fn from(source: PackchainError) -> Self
fn from(source: PackchainError) -> Self
Source§impl From<PackchainError> for ManageError
impl From<PackchainError> for ManageError
Source§fn from(source: PackchainError) -> Self
fn from(source: PackchainError) -> Self
Source§impl From<PackchainError> for PushError
impl From<PackchainError> for PushError
Source§fn from(source: PackchainError) -> Self
fn from(source: PackchainError) -> Self
Auto Trait Implementations§
impl !RefUnwindSafe for PackchainError
impl !UnwindSafe for PackchainError
impl Freeze for PackchainError
impl Send for PackchainError
impl Sync for PackchainError
impl Unpin for PackchainError
impl UnsafeUnpin for PackchainError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> ErrorExt for T
impl<T> ErrorExt for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> ToStringFallible for Twhere
T: Display,
impl<T> ToStringFallible for Twhere
T: Display,
Source§fn try_to_string(&self) -> Result<String, TryReserveError>
fn try_to_string(&self) -> Result<String, TryReserveError>
ToString::to_string, but without panic on OOM.