can1357/oh-my-pi · error
No session - artifacts unavailable
Error message
No session - artifacts unavailable
What it means
resolveArtifactFile (packages/coding-agent/src/internal-urls/artifact-protocol.ts:54) throws when artifactsDirsFromRegistry() yields zero session artifact directories — i.e. no session is registered in the AgentRegistry, so artifacts cannot exist anywhere. Artifacts are per-session; without an active session there is nothing to resolve against.
Source
Thrown at packages/coding-agent/src/internal-urls/artifact-protocol.ts:54
}
/** Resolve an `artifact://` URL to its backing file without reading artifact bytes. */
export async function resolveArtifactFile(url: InternalUrl, context?: ResolveContext): Promise<ResolvedArtifactFile> {
const id = parseArtifactId(url);
// Artifact ids are per-session counters; in multi-session hosts the same
// id exists in several dirs. Pin resolution to the calling session's
// artifacts dir first so `artifact://3` means *this* session's #3.
const dirs = artifactsDirsFromRegistry();
const pinnedDir = context?.localProtocolOptions?.getArtifactsDir?.() ?? null;
if (pinnedDir) {
const pinnedIndex = dirs.indexOf(pinnedDir);
if (pinnedIndex >= 0) dirs.splice(pinnedIndex, 1);
dirs.unshift(pinnedDir);
}
if (dirs.length === 0) {
throw new Error("No session - artifacts unavailable");
}
let foundPath: string | undefined;
let anyDirExists = false;
const availableIds = new Set<string>();
for (const dir of dirs) {
let files: string[];
try {
files = await fs.readdir(dir);
anyDirExists = true;
} catch (err) {
if (isEnoent(err)) continue;
throw err;
}
const match = files.find(f => f.startsWith(`${id}.`));
if (match) {
foundPath = path.join(dir, match);View on GitHub (pinned to 9690622007)
Solutions
- Start/open a session first so the registry has an artifacts directory, then resolve artifact:// URLs.
- Ensure the resolving code runs inside the session host process, not a separate process with an empty registry.
- If embedding, register the session with AgentRegistry so artifactsDirsFromRegistry() returns at least one dir.
- Guard callers: skip artifact:// resolution when no session is active and surface a user-facing message instead.
Example fix
// before
const res = await resolveArtifactFile(url); // throws if no session
// after
import { AgentRegistry } from "../registry/agent-registry";
if (AgentRegistry.global().list().length === 0) {
return "Artifacts are unavailable outside an active session.";
}
const res = await resolveArtifactFile(url); Defensive patterns
Strategy: try-catch
Validate before calling
import { AgentRegistry } from "../registry/agent-registry";
const hasSession = AgentRegistry.global().list().length > 0;
if (!hasSession) {
return "artifact:// URLs require an active session.";
} Type guard
function sessionAvailable(registry: { list(): unknown[] }): boolean {
return registry.list().length > 0;
} Try / catch
try {
const res = await resolveArtifactFile(url, context);
} catch (err) {
if (err instanceof Error && err.message === "No session - artifacts unavailable") {
return "Artifacts are unavailable outside an active session.";
}
throw err;
} Prevention
- Only expose artifact:// resolution to code running inside a live session host.
- Check the agent registry has at least one session before enabling artifact features.
- In SDK/embedding scenarios, initialize and register the session before resolving internal URLs.
- Avoid resolving artifacts in teardown/afterExit hooks after sessions are unregistered.
When it happens
Trigger: Resolving any artifact:// URL outside an active session: no sessions registered in AgentRegistry.global(), calling the protocol handler from a bare script/SDK context before a session starts, or after the registry was cleared on session teardown.
Common situations: Running artifact:// resolution in a standalone test or worker process that never opened a session; invoking the resolver after the CLI session exited; embedding the library without initializing the agent registry.
Related errors
- artifact:// URL requires a numeric ID: artifact://0
- artifact:// ID must be numeric, got: ${id}
- No artifacts directory found
- No active debug session. Launch or attach first.
- Marketplace "${catalog.name}" already exists
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/7c2e1cb5183bdf58.
Report an issue: GitHub.