can1357/oh-my-pi · error

Unknown agent: ${agentId}\nKnown agents: ${knownStr}\nList a

Error message

Unknown agent: ${agentId}\nKnown agents: ${knownStr}\nList all with history://

What it means

history://<agentId> resolves an agent to a live session or a retained session file. If the agent id matches no visible agent and no transcript can be recovered from disk, resolve throws listing the known agent ids and pointing to history:// for the full list.

Source

Thrown at packages/coding-agent/src/internal-urls/history-protocol.ts:104

		}

		let ref = registry.get(agentId);
		if (ref?.kind === "advisor") ref = undefined;
		if (!ref) {
			// Case-insensitive fallback: agent ids are human-typed (e.g. AuthLoader).
			const lower = agentId.toLowerCase();
			ref = visible.find(candidate => candidate.id.toLowerCase() === lower);
		}

		if (!ref) {
			// Registry miss — the agent may have been unregistered or lost on resume.
			// Serve its transcript straight from disk if the session file persists.
			const disk = await this.#resolveFromDisk(agentId, preferredArtifactDir);
			if (disk) return { ...disk, url: url.href };

			const known = visible.map(candidate => candidate.id);
			const knownStr = known.length > 0 ? known.join(", ") : "none";
			throw new Error(`Unknown agent: ${agentId}\nKnown agents: ${knownStr}\nList all with history://`);
		}

		const notes: string[] = [];
		let messages: unknown[];
		if (ref.session) {
			messages = ref.session.messages;
			notes.push("Source: live session");
		} else if (ref.sessionFile) {
			messages = await loadSessionMessagesReadOnly(ref.sessionFile);
			notes.push(`Source: session file (read-only, ${ref.status})`);
		} else {
			// No live session and no retained sessionFile — try the disk scan before
			// giving up, in case the transcript lingers under an artifacts dir.
			const disk = await this.#resolveFromDisk(ref.id, preferredArtifactDir);
			if (disk) return { ...disk, url: url.href };
			throw new Error(`Agent ${ref.id} has no transcript: session is gone and no session file was retained`);
		}

View on GitHub (pinned to 9690622007)

Solutions

  1. Use one of the 'Known agents: ...' ids from the message
  2. Call history:// (no id) to list all agents and copy the exact id
  3. If the transcript matters, locate the session file manually before it is cleaned up

Example fix

// before
await resolve('history://agnt_12')
// after
await resolve('history://agent_12ab') // exact id from history:// listing
Defensive patterns

Strategy: validation

Validate before calling

const agents = await resolve('history://') // list
const ids = extractAgentIds(agents)
if (!ids.includes(agentId)) throw new Error(`unknown agent ${agentId}; known: ${ids.join(', ')}`)

Try / catch

try {
  return await resolve(`history://${agentId}`)
} catch (err) {
  if (String(err).startsWith('Unknown agent:')) {
    const list = await resolve('history://')
    logger.warn('agent not found, listing known', { agentId })
    return list
  }
  throw err
}

Prevention

When it happens

Trigger: Calling history://<agentId> (via resolve) with an id that is neither a live/known agent nor recoverable from the artifacts directory scan.

Common situations: Typo'd or shortened agent id; referencing an agent from a previous process run whose session file was deleted; confusing session ids with agent ids.

Related errors


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