GitoxideLabs/gitoxide · error

pasted object is not a commit

Error message

pasted object is not a commit

What it means

`resolve_pasted_commit` successfully resolved the pasted hex to an object, but that object is not of kind `gix::object::Kind::Commit`. The function contractually returns a commit ID, so non-commit objects (blob, tree, tag-object) are rejected with this `ensure!`.

Solutions

  1. Paste a commit object ID: get one with `git rev-parse <ref>^{commit}`.
  2. If you have a tag object ID, peel it first: `git rev-parse <tag>^{}` resolves to the commit.
  3. If you have a blob/tree ID, look up the containing commit instead of pasting the raw object ID.
  4. To support other kinds, check `object.kind` in `resolve_pasted_commit` and peel tags via `object.peel_to_kind(Kind::Commit)` before rejecting.

Example fix

// before
let object = repo.rev_parse(hex)?.single()?.object()?;
anyhow::ensure!(object.kind == Kind::Commit, "pasted object is not a commit");
// after
let object = repo.rev_parse(hex)?.single()?.object()?;
let commit = object.peel_to_kind(gix::object::Kind::Commit)
    .context("pasted object does not peel to a commit")?;
Defensive patterns

Strategy: validation

Validate before calling

let kind = repo.rev_parse(pasted.trim().as_bytes().as_bstr())?
    .single().ok()
    .and_then(|id| id.object().ok())
    .map(|o| o.kind);
if kind != Some(gix::object::Kind::Commit) { /* peel or reject before calling */ }

Type guard

fn is_commit_object(kind: gix::object::Kind) -> bool {
    kind == gix::object::Kind::Commit
}

Try / catch

match resolve_pasted_commit(&repo, pasted) {
    Err(e) if e.to_string().contains("pasted object is not a commit") => {
        eprintln!("Peel tags / use the containing commit: git rev-parse <id>^{{commit}}");
    }
    res => res?,
}

Prevention

When it happens

Trigger: Pasting the hex ID of a blob or tree (e.g. copied from `git ls-tree` or `git cat-file` output) into the commit-paste flow, or a lightweight tag's target ambiguity where the resolved object is the tagged blob/tree (gix-tix/src/lib.rs:7028).

Common situations: Copy-pasting object IDs from `git cat-file --batch-check`, GitHub URLs that reference blobs (`/blob/<sha>`), or tree IDs from tree listings; repos where a tag object was pasted (tag kind, not commit).

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/9f482f5f375612f6. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/lib.rs:7028

            })
        }
    }
}

fn resolve_pasted_commit(repository: &gix::Repository, pasted: &str) -> Result<gix::ObjectId> {
    let hash = pasted.trim();
    anyhow::ensure!(
        !hash.is_empty() && hash.bytes().all(|byte| byte.is_ascii_hexdigit()),
        "expected exactly one hexadecimal commit ID"
    );
    let object = repository
        .rev_parse(hash.as_bytes().as_bstr())
        .context("could not resolve pasted commit ID")?
        .single()
        .context("pasted commit ID is ambiguous")?
        .object()
        .context("could not read pasted object")?;
    anyhow::ensure!(
        object.kind == gix::object::Kind::Commit,
        "pasted object is not a commit"
    );
    Ok(object.id)
}

fn diagnostic_key(character: char) -> KeyEvent {
    let code = match character {
        '\t' => KeyCode::Tab,
        '\n' | '\r' => KeyCode::Enter,
        '\u{1b}' => KeyCode::Esc,
        character => KeyCode::Char(character),
    };
    let modifiers = if character.is_uppercase() {
        KeyModifiers::SHIFT
    } else {
        KeyModifiers::NONE
    };

View on GitHub (pinned to e73179060b)