can1357/oh-my-pi · error · Error
Entry ${branchFromId} not found
Error message
Entry ${branchFromId} not found What it means
branch() moves the session leaf to an earlier entry so subsequent appends form a new branch of the entry tree. It throws if branchFromId does not exist in the session index, since there is no entry to move the leaf to. Existing entries are never modified or deleted; the id must point at a live entry in the currently loaded session.
Source
Thrown at packages/coding-agent/src/session/session-manager.ts:2613
/** All session entries (excludes header). Returns a shallow copy. */
getEntries(): SessionEntry[] {
return [...this.#entries];
}
/**
* The session as a tree. A well-formed session has exactly one root; orphaned
* entries (broken parent chain) are returned as roots too.
*/
getTree(): SessionTreeNode[] {
return this.#index.tree(this.#entries);
}
/**
* Move the leaf to an earlier entry so the next append forms a new branch.
* Existing entries are never modified or deleted.
*/
branch(branchFromId: string): void {
if (!this.#index.has(branchFromId)) throw new Error(`Entry ${branchFromId} not found`);
this.#setLeaf(branchFromId);
}
/** Reset the leaf to null so the next append creates a new root entry. */
resetLeaf(): void {
this.#setLeaf(null);
}
/**
* Durably move the active branch past a discarded entry.
*
* The loader reconstructs the active branch from the last physical journal
* entry, so changing the in-memory leaf alone is lost on reload. Known
* metadata children are chained onto the discarded entry's parent before the
* entry is removed. If any child may carry content, the subtree is preserved
* off-branch instead. Both paths append a metadata-only branch marker and
* rewrite the journal, making the selected path durable.
*/View on GitHub (pinned to 9690622007)
Solutions
- Fetch valid entry ids from the current SessionManager (entry list / traversal) instead of cached ids.
- Use resetLeaf() if you actually want to branch from a fresh root rather than an existing entry.
- Verify the target entry exists in the index before calling branch.
- Load the session containing the target entry before branching.
Example fix
// before mgr.branch(cachedId); // Entry <id> not found // after const entries = mgr.getEntries(); const target = entries.find(e => e.id === cachedId); if (target) mgr.branch(target.id); else mgr.resetLeaf();
Defensive patterns
Strategy: validation
Validate before calling
if (!mgr.hasEntry(branchFromId)) {
mgr.resetLeaf(); // branch from a fresh root instead
return;
} Type guard
function canBranch(mgr, id) {
return mgr.getEntry(id) != null;
} Try / catch
try {
mgr.branch(id);
} catch (err) {
if (/Entry .* not found/.test(err.message)) {
mgr.resetLeaf(); // fall back to a new root branch
} else throw err;
} Prevention
- Re-fetch entry ids from the live session before forking.
- Use resetLeaf() when you want a brand-new root instead of a specific entry.
- Reload the containing session before branching on ids read from a session file.
When it happens
Trigger: Calling SessionManager.branch(branchFromId) with an id not in the current session — id from a different session/file, an entry removed by compaction, or a stale id after the session was reloaded or reset.
Common situations: Building a 'fork from earlier message' UI that cached entry ids across a session reload; forking from another session's transcript; branching from an id destroyed by compaction.
Related errors
- Entry ${parentId} not found
- Entry ${targetId} not found
- Entry ${leafId} not found
- unknown function: {0}
- unknown key binding function: {0}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/cce5bc583b16c618.
Report an issue: GitHub.