can1357/oh-my-pi · error · Error
error
Error message
error
What it means
computeDependencyOrder(plan.commits) returns a discriminated result; when it contains an `error` field (a cycle or unresolvable ordering among the planned commits), runSplitCommit() rethrows it. This happens after user confirmation but before any commits are created, so the index is still intact.
Source
Thrown at packages/coding-agent/src/commit/agentic/index.ts:310
details: commit.details,
issueRefs: commit.issueRefs,
};
const message = formatCommitMessage(analysis, commit.summary);
process.stdout.write(`Commit ${index + 1}:\n${message}\n`);
const changeSummary = commit.changes.map(change => formatFileChangeSummary(change.path, change)).join(", ");
process.stdout.write(`Changes: ${changeSummary}\n`);
}
return;
}
if (!(await confirmSplitCommitPlan(plan))) {
process.stdout.write("Split commit aborted by user.\n");
return;
}
const order = computeDependencyOrder(plan.commits);
if ("error" in order) {
throw new Error(order.error);
}
process.stdout.write("● Creating split commits...\n");
const stagedDiff = await repo.diffText({ cached: true, binary: true });
await repo.unstage([]);
for (const [position, commitIndex] of order.entries()) {
const commit = plan.commits[commitIndex];
await repo.stageHunks(commit.changes, stagedDiff);
const analysis: ConventionalAnalysis = {
type: commit.type,
scope: commit.scope,
details: commit.details,
issueRefs: commit.issueRefs,
};
const message = formatCommitMessage(analysis, commit.summary);
try {
await repo.commitCreate(message, {});
} catch (error) {View on GitHub (pinned to 9690622007)
Solutions
- Re-run and request a different split, or edit the plan so each commit's changes are independent
- Merge the conflicting planned commits into a single commit
- Abort split mode and make one regular commit containing all staged changes
- Check the order.error message — it names the specific dependency conflict to untangle
Example fix
// before: plan has commit 'feat: api' and 'fix: api types' touching the same hunks cyclically
// after: combine them
{ "commits": [{ "type": "feat", "scope": "api", "summary": "add endpoint with types", "changes": [/* both file sets */] }] } Defensive patterns
Strategy: try-catch
Validate before calling
const order = computeDependencyOrder(plan.commits);
if ("error" in order) {
console.error("Plan not executable:", order.error);
// fall back to single commit before staging anything
} Type guard
function isOrderError(order: ReturnType<typeof computeDependencyOrder>): order is { error: string } {
return "error" in order;
} Try / catch
try {
await runSplitCommit(plan, ctx);
} catch (err) {
// nothing was committed yet (throw happens pre-staging); safe to retry as one commit
await runSingleCommit(generateFallbackProposal(numstat), ctx);
} Prevention
- Keep planned commits disjoint — one file per commit where possible
- Review the plan for commits touching the same files
- Prefer merging tightly coupled changes into one planned commit
When it happens
Trigger: The agent's split plan contains commits whose file changes depend on each other in a cyclic or unorderable way (e.g. commit A touches a file commit B also touches with conflicting dependency edges), making a sequential stage-hunks order impossible.
Common situations: Overlapping file changes across planned commits; the LLM splits one logical change into two commits that each need the other's hunks; lockfile/hunk interdependencies the planner cannot serialize.
Related errors
- Split commit plan missing staged files: ${missingFiles.join(
- Commit agent did not provide a proposal.
- Generated commit message failed validation: ${generated.vali
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/55ec6eaf30e89ff8.
Report an issue: GitHub.