can1357/oh-my-pi · error · Error

Entry ${targetId} not found

Error message

Entry ${targetId} not found

What it means

appendLabelChange writes a label entry that targets an existing entry by id (targetId). If the target id is absent from the session index, the label would reference a nonexistent entry, so the call throws before recording anything. Only labels on live entries in the currently loaded session are allowed.

Source

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

	getEntry(id: string): SessionEntry | undefined {
		return this.#index.get(id);
	}

	/** All direct children of an entry. */
	getChildren(parentId: string): SessionEntry[] {
		return this.#index.childrenOf(parentId);
	}

	getLabel(id: string): string | undefined {
		return this.#index.labelFor(id);
	}

	/**
	 * Set or clear a label on an entry. Pass undefined/empty to clear.
	 */
	appendLabelChange(targetId: string, label: string | undefined): string {
		if (!this.#index.has(targetId)) throw new Error(`Entry ${targetId} not found`);

		const entry: LabelEntry = { type: "label", ...this.#freshEntryFields(), targetId, label };
		this.#recordEntry(entry);
		return entry.id;
	}

	/**
	 * Walk from an entry to root, returning entries in path order. Includes all
	 * entry types; use buildSessionContext() for the resolved LLM messages.
	 */
	getBranch(fromId?: string): SessionEntry[] {
		return this.#index.pathTo(fromId ?? this.#index.leafId());
	}

	/**
	 * Build the session context (LLM messages), or — with `{ transcript: true }` —
	 * the full-history display transcript, from the current leaf path.
	 */

View on GitHub (pinned to 9690622007)

Solutions

  1. Refresh the entry list from the current SessionManager and use a currently valid entry id.
  2. Check the target still exists before labelling (lookup/getEntry first).
  3. Reload or switch to the session that actually contains the target entry.
  4. Skip labels for entries missing from the index (they were compacted away).

Example fix

// before
mgr.appendLabelChange(oldId, "done"); // may throw
// after
const target = mgr.getEntry(oldId);
if (target) mgr.appendLabelChange(oldId, "done");
Defensive patterns

Strategy: validation

Validate before calling

if (!mgr.hasEntry(targetId)) {
  return; // entry was compacted away or belongs to another session
}

Type guard

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

Try / catch

try {
  mgr.appendLabelChange(targetId, label);
} catch (err) {
  if (/Entry .* not found/.test(err.message)) {
    logger.warn("Label target missing; skipping", { targetId });
  } else throw err;
}

Prevention

When it happens

Trigger: Calling appendLabelChange(targetId, label) with an id not present in the current session's entry index — id from another session, pruned by compaction, fabricated, or from a stale in-memory list after reloading the session file.

Common situations: Labelling entries after the session was compacted (old ids gone); mixing ids across branched sessions; UI holding stale selection while the session reloaded underneath it.

Related errors


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