Skip to main content

PackchainError

Enum PackchainError 

Source
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.

Fields

§found: u32

Version found in the parsed JSON.

§expected: u32

Version this build expects.

§

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

§found: String

The rejected string (truncated by Display’s default formatter at the wire level).

§

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.

Fields

§bytes: Vec<u8>

The offending bytes from the tree entry’s filename.

§

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.

Fields

§ref_name: String

The ref name the fetch asked about.

§

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.

Fields

§key: String

Bucket-relative pack key recorded in chain.json.

§

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.

Fields

§key: String

Bucket key of the missing <full_at>.bundle.

§

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: StorageEngine

Engine 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: String

The ref name read::read_blob was asked about.

§

PathNotFound

Caller passed a path that does not exist in this commit’s tree.

Fields

§ref_name: String

Ref the lookup ran against.

§path: String

The path the caller asked for, returned verbatim.

§

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

§path: String

The rejected path, returned verbatim.

§reason: &'static str

Human-readable reason ("empty", "absolute", "contains ..\"", etc.).

§

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”.

Fields

§path: String

The path the caller asked for.

§

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.

Fields

§sha: String

The blob SHA the path-index named.

§path: String

The path the caller asked for.

§

MalformedPackEntry

Pack entry header could not be decoded (truncated bytes, unknown type id, non-canonical size encoding, etc.).

Fields

§offset: u64

Pack-relative offset of the entry that failed to decode.

§reason: String

Human-readable reason from the underlying decoder.

§

Decompress

Zlib stream embedded in a pack entry could not be inflated.

Fields

§offset: u64

Pack-relative offset of the entry whose payload failed.

§

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: u32

The depth limit (always read::MAX_DELTA_DEPTH).

§

MalformedDelta

Delta payload could not be applied (truncated instructions, out-of-range copy span, source size mismatch).

Fields

§reason: &'static str

Human-readable reason from the delta decoder.

§

InvalidRefName

read_blob was given a ref name that fails gix-validate’s reference-name rules (empty, control characters, .., etc.).

Fields

§name: String

The ref name the caller passed.

§

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.

Fields

§oid: String

The tree OID whose presence in the ancestor set was detected.

§

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

§ref_name: String

The ref the lookup ran against.

§chain_tip: String

Tip recorded in chain.json at read time.

§path_index_tip: String

Tip recorded in path-index.json at read time.

§

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).

Fields

§last_missing_key: String

The key whose final PackMissing ended the retry loop.

§attempts: u32

Number of retry attempts that were made (excluding the initial attempt). Pinned in the error so logs and tests can assert on it.

Trait Implementations§

Source§

impl Debug for PackchainError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PackchainError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PackchainError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for PackchainError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for PackchainError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for PackchainError

Source§

fn from(value: Error) -> Self

Converts to this type from the input type.
Source§

impl From<GitError> for PackchainError

Source§

fn from(source: GitError) -> Self

Converts to this type from the input type.
Source§

impl From<JoinError> for PackchainError

Source§

fn from(value: JoinError) -> Self

Converts to this type from the input type.
Source§

impl From<ObjectStoreError> for PackchainError

Source§

fn from(source: ObjectStoreError) -> Self

Converts to this type from the input type.
Source§

impl From<PackchainError> for FetchError

Source§

fn from(source: PackchainError) -> Self

Converts to this type from the input type.
Source§

impl From<PackchainError> for ManageError

Source§

fn from(source: PackchainError) -> Self

Converts to this type from the input type.
Source§

impl From<PackchainError> for PushError

Source§

fn from(source: PackchainError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ErrorExt for T
where T: Error + Send + Sync + 'static,

Source§

fn raise(self) -> Exn<Self>
where Self: Sized,

Raise this error as a new exception.
Source§

fn and_raise<T>(self, context: T) -> Exn<T>
where T: Error + Send + Sync + 'static, Self: Sized,

Raise this error as a child of a new exception with the given context error. Read more
Source§

fn raise_erased(self) -> Exn
where Self: Sized,

Raise this error as a new exception, with type erasure.
Source§

fn raise_all<T, I>(self, sources: I) -> Exn<Self>
where Self: Sized, T: Error + Send + Sync + 'static, I: IntoIterator, <I as IntoIterator>::Item: Into<Exn<T>>,

Raise this error as a new exception, with sources as causes.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> ToStringFallible for T
where T: Display,

Source§

fn try_to_string(&self) -> Result<String, TryReserveError>

ToString::to_string, but without panic on OOM.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more