can1357/oh-my-pi · error

No session - agent outputs unavailable

Error message

No session - agent outputs unavailable

What it means

Agent outputs live in per-session artifacts directories discovered via AgentRegistry and artifactsDirsFromRegistry(). If the registry yields zero directories — meaning no session has ever been registered (optionally with the caller's sessionFile persisted via ensurePersistedRoster first) — there is nowhere to resolve the output ID and the handler throws. This is an environment/state error, not a URL-shape error.

Source

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

		}

		const registry = AgentRegistry.global();
		const rootSessionFile = context?.sessionFile
			? await ensurePersistedRoster(registry, context.sessionFile)
			: undefined;
		// The caller root's canonical artifact directory (its session file minus
		// the `.jsonl` suffix) is scanned FIRST, ahead of every process-global
		// registry dir. The roster ref this refresh installs for the caller's
		// parked id contributes only its nested child dir, not the root dir that
		// actually holds `<id>.md` — and with two coexisting roots the global
		// `Main` ref can belong to the other root, whose dir would otherwise win
		// the first-hit id map for a shared id. No caller session file: keep the
		// pre-existing global scan untouched.
		const dirs = artifactsDirsFromRegistry(
			rootSessionFile ? { preferredDir: rootSessionFile.slice(0, -6) } : undefined,
		);
		if (dirs.length === 0) {
			throw new Error("No session - agent outputs unavailable");
		}

		// A subagent allocates its own children as dot-qualified ids
		// (`Parent.Child`), so the slash path form is first tried as a hierarchy
		// separator: `agent://Parent/Child` resolves `Parent.Child.md`. Only when
		// no such nested output exists does the path fall back to jq-style JSON
		// extraction on `<outputId>.md`. Query form (`?q=`) is always extraction.
		const pathSegments = hasPathExtraction ? urlPath.split("/").filter(Boolean) : [];
		const decodedSegments = pathSegments.map(segment => {
			try {
				return decodeURIComponent(segment);
			} catch {
				return segment;
			}
		});
		const nestedId =
			decodedSegments.length > 0 && decodedSegments.every(segment => !segment.includes("."))
				? [outputId, ...decodedSegments].join(".")

View on GitHub (pinned to 9690622007)

Solutions

  1. Ensure an agent session is registered in AgentRegistry.global() before resolving agent:// URLs
  2. Pass a valid context.sessionFile in ResolveContext so ensurePersistedRoster can seed the artifacts dir
  3. Verify the session artifacts directories exist on disk for the running session

Example fix

// before
const res = await handler.resolve(url); // no context, no sessions registered
// after
const res = await handler.resolve(url, { sessionFile: "/path/to/session.jsonl" });
Defensive patterns

Strategy: try-catch

Validate before calling

const dirs = artifactsDirsFromRegistry();
if (dirs.length === 0) {
  // register a session or pass context.sessionFile before resolving
}

Try / catch

try {
  const resource = await handler.resolve(url, context);
} catch (err) {
  if (err instanceof Error && err.message === "No session - agent outputs unavailable") {
    // register a session / pass context.sessionFile, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: Calling resolve() with no registered agent sessions, or with a context.sessionFile that fails to persist a roster so no artifact dirs can be derived — artifactsDirsFromRegistry() returns an empty array.

Common situations: Invoking an agent:// URL resolution outside of an active session (scripts, tests, SDK usage without booting the registry); calling from a context where context.sessionFile is undefined and no global sessions exist yet; sessions that were cleaned up or whose registry state was lost after a restart.

Related errors


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