can1357/oh-my-pi · error · Error

Entry ${parentId} not found

Error message

Entry ${parentId} not found

What it means

appendMessage records a message entry with an explicit parentId to build the session's entry tree. If a non-null parentId is not present in the session entry index, the tree would be corrupted (an orphan entry), so the call throws. parentId must reference an entry already recorded in this session, or be null to append at the root.

Source

Thrown at packages/coding-agent/src/session/session-manager.ts:2287

		this.#recordEntry(entry);
		return entry.id;
	}

	/**
	 * Append to a non-active branch without changing the current leaf.
	 * Used by work that retains ownership of a branch across tree navigation.
	 */
	appendMessageToBranch(
		message:
			| Message
			| CustomMessage
			| HookMessage
			| BashExecutionMessage
			| PythonExecutionMessage
			| FileMentionMessage,
		parentId: string | null,
	): string {
		if (parentId !== null && !this.#index.has(parentId)) throw new Error(`Entry ${parentId} not found`);
		const activeLeafId = this.#index.leafId();
		const entry: SessionMessageEntry = {
			type: "message",
			id: generateId(this.#index),
			parentId,
			timestamp: nowIso(),
			message,
		};
		this.#recordEntry(entry);
		this.#index.setLeaf(activeLeafId);
		return entry.id;
	}

	/** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */
	appendThinkingLevelChange(thinkingLevel?: string, configured?: string): string {
		const entry: ThinkingLevelChangeEntry = {
			type: "thinking_level_change",
			...this.#freshEntryFields(),

View on GitHub (pinned to 9690622007)

Solutions

  1. Use ids only from the same SessionManager instance (values returned by append*/getEntry APIs).
  2. Pass null as parentId to append at the current leaf instead of a stale id.
  3. Re-resolve the parent id via the entry index/leaf API after compaction or branching.
  4. Check that the right session (file) is loaded before appending.

Example fix

// before
mgr.appendMessage(msg, staleEntryId); // Entry <id> not found
// after
const parentId = mgr.getLeafId(); // current valid entry id or null
mgr.appendMessage(msg, parentId);
Defensive patterns

Strategy: validation

Validate before calling

if (parentId !== null && !mgr.hasEntry(parentId)) {
  parentId = null; // append at leaf instead of orphaning
}

Type guard

function entryExists(mgr, id) {
  return id === null || mgr.getEntry(id) != null;
}

Try / catch

try {
  mgr.appendMessage(msg, parentId);
} catch (err) {
  if (/Entry .* not found/.test(err.message)) {
    mgr.appendMessage(msg, mgr.getLeafId());
  } else throw err;
}

Prevention

When it happens

Trigger: Calling appendMessage with a parentId that was never returned by this session manager (entry from another session, entry pruned by compaction, an id from a file loaded into a different manager instance, or a stale id after branching/undo).

Common situations: Reusing entry IDs across session instances; referencing an entry removed/compacted away; passing a fabricated id; resuming a different session file while holding old entry ids in memory.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/c44a7eff2bceb812. Report an issue: GitHub.