GitoxideLabs/gitoxide · error

Tried to use as tree, but was

Error message

Tried to use {} as tree, but was {}

What it means

This panic comes from `Object::into_tree()` in gix, a non-fallible convenience API that converts a generic `Object` handle into a `Tree`. The library throws it because the object the handle points to is not actually a tree (its kind was Blob, Commit, or Tag). Since `into_tree` is deliberately a panic-based variant of `try_into_tree`, misuse is a caller logic bug rather than a recoverable library error.

Solutions

  1. Check the object kind before converting: only call `into_tree()` when `object.kind == gix::object::Kind::Tree`.
  2. Use the fallible variant `try_into_tree()` and handle the `Err` case, which returns the original object instead of panicking.
  3. If starting from a rev/ref, peel explicitly with `rev.peel_to_tree()` (or `object.peel_to_kind(gix::object::Kind::Tree)`) to resolve tags/commits down to their tree.
  4. Verify the id being passed actually denotes a tree (e.g. `git cat-file -t <id>` returns `tree`).

Example fix

// before
let tree = repo.find_object(id)?.into_tree();

// after
let object = repo.find_object(id)?;
let tree = match object.kind {
    gix::object::Kind::Tree => object.try_into_tree().expect("kind checked as tree"),
    _ => object.peel_to_kind(gix::object::Kind::Tree)?.try_into_tree().expect("peeled to tree"),
};
Defensive patterns

Strategy: type-guard

Validate before calling

let object = repo.find_object(tree_id)?;
if object.kind != gix::object::Kind::Tree {
    return Err(anyhow::anyhow!("id {} is {:?}, not a tree", tree_id, object.kind));
}

Type guard

fn as_tree(object: gix::Object<'_>) -> Option<gix::Tree<'_>> {
    (object.kind == gix::object::Kind::Tree).then(|| object.try_into_tree().expect("kind checked"))
}

Try / catch

// Prefer the fallible API instead of catching a panic
let tree = match object.try_into_tree() {
    Ok(tree) => tree,
    Err(obj) => return Err(anyhow::anyhow!("object {} was {:?}, not a tree", obj.id, obj.kind)),
};

Prevention

When it happens

Trigger: Calling `repo.find_object(id)?.into_tree()` (or `object.into_tree()`) when the object id resolves to a blob, commit, or tag instead of a tree. Typically happens after resolving an abbreviated id, a ref name, or iterating mixed objects without checking `object.kind`.

Common situations: Passing a commit id (e.g. from `HEAD`) where a tree id was expected; forgetting to call `.peel_to_tree()` first; iterating tree entries that reference blobs and blindly converting each object; using a tag object id directly instead of peeling it.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/d8d9a57cf747b25c. Report an issue: GitHub.

Appendix: source

Thrown at gix/src/object/mod.rs:88

            kind,
            data,
            repo,
        }
    }

    /// Transform this object into a blob, or panic if it is none.
    pub fn into_blob(self) -> Blob<'repo> {
        match self.try_into() {
            Ok(blob) => blob,
            Err(this) => panic!("Tried to use {} as blob, but was {}", this.id, this.kind),
        }
    }

    /// Transform this object into a tree, or panic if it is none.
    pub fn into_tree(self) -> Tree<'repo> {
        match self.try_into() {
            Ok(tree) => tree,
            Err(this) => panic!("Tried to use {} as tree, but was {}", this.id, this.kind),
        }
    }

    /// Transform this object into a commit, or panic if it is none.
    pub fn into_commit(self) -> Commit<'repo> {
        match self.try_into() {
            Ok(commit) => commit,
            Err(this) => panic!("Tried to use {} as commit, but was {}", this.id, this.kind),
        }
    }

    /// Transform this object into a tag, or panic if it is none.
    pub fn into_tag(self) -> Tag<'repo> {
        match self.try_into() {
            Ok(tag) => tag,
            Err(this) => panic!("Tried to use {} as tag, but was {}", this.id, this.kind),
        }
    }

View on GitHub (pinned to e73179060b)