theonedev/onedev · critical · ExplicitException
%s (project id: %d, ref: %s)
Error message
%s (project id: %d, ref: %s)
What it means
Thrown by DefaultCommitInfoService while walking refs during commit info collection: a ref points to an object id that is missing from the object database (MissingObjectException), which JGit wraps into an ExplicitException annotated with the project id and ref name. It indicates repository corruption — a dangling ref referencing a pruned or never-delivered object.
Source
Thrown at server-core/src/main/java/io/onedev/server/xodus/DefaultCommitInfoService.java:984
for (Object work : works) {
if (work instanceof CollectingWork) {
collectingWorks.add((CollectingWork) work);
} else if (work instanceof CheckingWork) {
try (RevWalk revWalk = new RevWalk(projectService.getRepository(projectId))) {
Collection<Ref> refs = new ArrayList<>();
refs.addAll(projectService.getRepository(projectId).getRefDatabase()
.getRefsByPrefix(Constants.R_HEADS));
refs.addAll(projectService.getRepository(projectId).getRefDatabase()
.getRefsByPrefix(Constants.R_TAGS));
for (Ref ref : refs) {
RevObject revObj;
try {
revObj = revWalk.peel(revWalk.parseAny(ref.getObjectId()));
} catch (MissingObjectException e) {
var message = String.format("%s (project id: %d, ref: %s)", e.getMessage(),
projectId, ref.getName());
throw new ExplicitException(message);
}
if (revObj instanceof RevCommit) {
RevCommit commit = (RevCommit) revObj;
collectingWorks.add(new CollectingWork(CHECK_PRIORITY, commit.copy(),
commit.getCommitTime(), ref.getName()));
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
collectingWorks.sort(new CommitTimeComparator());
for (CollectingWork work : collectingWorks)
doCollect(project, work.getCommitId(), work.getRefName());
});
}View on GitHub (pinned to d44925c47c)
Solutions
- Delete or fix the offending ref (git update-ref -d <ref>) then re-run the operation.
- Run 'git fsck --full' on the project repository to enumerate all corruption.
- Re-fetch from the canonical remote to restore missing objects.
- Restore the repository from backup if corruption is extensive.
Example fix
// before git update-ref refs/heads/broken refs/heads/broken // after: remove ref pointing to missing object git update-ref -d refs/heads/broken git fetch origin '+refs/heads/*:refs/heads/*'
Defensive patterns
Strategy: try-catch
Try / catch
try { collectCommitInfo(projectId); } catch (ExplicitException e) { if (e.getMessage().contains("MissingObject")) repairRepository(projectId); } Prevention
- Never interrupt git gc/prune; ensure adequate disk space
- Schedule periodic git fsck checks on project repositories
- Verify object completeness after repository migrations or backups
When it happens
Trigger: A ref (branch/tag) in the project's git repository points to a commit/tree/blob that does not exist in the pack files or loose objects — typically after interrupted gc/prune, failed fetch replication, or manual object deletion.
Common situations: Disk-full or killed 'git gc' left refs without objects; repository migrated/copied incompletely; fetch/prune removed objects a stale ref still targets; corrupted storage after crash.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- RefUpdateException
- Ref name is required when commit hash is specified
- Either commit hash, branch or tag should be specified
- Unable to find commit to import build spec (import project:
- No default branch in project:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/54038b6d8b5eb957.
Report an issue: GitHub.