theonedev/onedev · error · IllegalStateException
Commits have already been marked as start.
Error message
Commits have already been marked as start.
What it means
RevWalk.assertNoCommitsMarkedStart() guards APIs (added in 5.5) that must be configured before any start commits exist. Once markStart/markUninteresting (roots) have been called, changing certain settings would invalidate the pending start set, so this IllegalStateException is thrown while roots is non-empty.
Source
Thrown at server-core/src/main/java/org/eclipse/jgit/revwalk/RevWalk.java:1741
protected void assertNotStarted() {
if (isNotStarted())
return;
throw new IllegalStateException(
JGitText.get().outputHasAlreadyBeenStarted);
}
/**
* Throws an exception if any commits have been marked as start.
* <p>
* If {@link #markStart(RevCommit)} has already been called,
* {@link #reset()} can be called to satisfy this condition.
*
* @since 5.5
*/
protected void assertNoCommitsMarkedStart() {
if (roots.isEmpty())
return;
throw new IllegalStateException(
JGitText.get().commitsHaveAlreadyBeenMarkedAsStart);
}
private boolean isNotStarted() {
return pending instanceof StartGenerator;
}
/**
* Create and return an {@link org.eclipse.jgit.revwalk.ObjectWalk} using
* the same objects.
* <p>
* Prior to using this method, the caller must reset this RevWalk to clean
* any flags that were used during the last traversal.
* <p>
* The returned ObjectWalk uses the same ObjectReader, internal object pool,
* and free RevFlags. Once the ObjectWalk is created, this RevWalk should
* not be used anymore.
*View on GitHub (pinned to d44925c47c)
Solutions
- Move the configuration call above all markStart/markUninteresting invocations.
- Create a new RevWalk, configure first, then mark start commits.
- Refactor so start marking is the last step of walk setup.
Example fix
// before walk.markStart(head); walk.setRetainBody(false); // assertNoCommitsMarkedStart throws // after walk.setRetainBody(false); walk.markStart(head);
Defensive patterns
Strategy: validation
Validate before calling
if (!walk.roots.isEmpty()) // roots are registered by markStart
throw new IllegalStateException("mark start commits only after configuration"); Type guard
// structural guard: keep marking in one terminal method
void buildWalk(RevWalk w, Consumer<RevWalk> config, RevCommit... starts) throws IOException {
config.accept(w); // all settings first
for (RevCommit c : starts) w.markStart(c); // marking last
} Try / catch
try {
configure(walk);
} catch (IllegalStateException e) {
walk = new RevWalk(repo);
configure(walk);
walk.markStart(head);
} Prevention
- Make markStart the last step of walk construction
- Avoid helpers with markStart side effects called mid-setup
- Rebuild the walk instead of mutating after marking
When it happens
Trigger: Calling an API that asserts no start commits (e.g. setCommitSpooling mode or related pre-start configuration) after markStart(...) has already registered roots on the walk.
Common situations: Constructing a walk, marking start commits early, then applying late configuration; helper methods marking starts as a side effect before configuration code runs.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Output has already been started.
- Shallow commits have already been initialized.
- Cannot combine TreeFilter {0} with RevFilter {1}.
- Cannot find merge base using first parent.
- Cannot combine topo sort with topo-keep-branch-together sort
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/d2cbc0f85ab55bee.
Report an issue: GitHub.