can1357/oh-my-pi · error

No artifacts directory found

Error message

No artifacts directory found

What it means

After gathering the candidate artifacts directories, #findOutput() reports whether any of them actually exists on disk (anyDirExists). If none exist (all readdir calls hit ENOENT), the handler throws 'No artifacts directory found'. Distinct from error 1502: the registry produced directory paths, but none of them exist on the filesystem.

Source

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

		// 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(".")
				: undefined;

		const scan = await this.#findOutput(dirs, nestedId ? [nestedId, outputId] : [outputId]);
		if (!scan.anyDirExists) {
			throw new Error("No artifacts directory found");
		}
		if (!scan.foundPath) {
			const target = nestedId ?? outputId;
			const availableStr = scan.availableIds.size > 0 ? [...scan.availableIds].join(", ") : "none";
			throw new Error(`Not found: ${target}\nAvailable: ${availableStr}`);
		}

		const rawContent = await Bun.file(scan.foundPath).text();
		const notes: string[] = [];
		let content = rawContent;
		let contentType: InternalResource["contentType"] = "text/markdown";

		// Extraction applies only when the URL did NOT resolve to a nested output
		// (a slash that named a real child is a hierarchy hop, not a jq path).
		const extract = hasQueryExtraction || (hasPathExtraction && scan.matchedId !== nestedId);
		if (extract) {
			let jsonValue: unknown;
			try {

View on GitHub (pinned to 9690622007)

Solutions

  1. Confirm the artifacts directory for the current session exists (session file path minus '.jsonl')
  2. Run an agent to produce at least one output so the artifacts dir is created
  3. If dirs were deleted intentionally, re-register a fresh session before resolving agent:// URLs

Example fix

// before
const res = await handler.resolve(parseUrl("agent://out1"), { sessionFile: deletedSession });
// after
// ensure the artifacts dir exists or use a session whose artifacts dir is present
const res = await handler.resolve(parseUrl("agent://out1"), { sessionFile: liveSession });
Defensive patterns

Strategy: fallback

Validate before calling

import { existsSync } from "node:fs";
const dirs = artifactsDirsFromRegistry();
if (!dirs.some(d => existsSync(d))) {
  // artifacts dirs are gone; re-run an agent to recreate them
}

Try / catch

try {
  const resource = await handler.resolve(url, context);
} catch (err) {
  if (err instanceof Error && err.message === "No artifacts directory found") {
    // fall back: regenerate the output or surface 'artifacts unavailable'
  } else throw err;
}

Prevention

When it happens

Trigger: artifactsDirsFromRegistry() returns one or more dir paths but every one of them is missing on disk — e.g. resolving agent://<id> after session artifacts were deleted, or with a preferredDir derived from a sessionFile whose sibling artifacts dir was never created.

Common situations: Pointing at a session file whose artifacts dir was removed or never written (fresh session with no outputs yet); stale registry entries pointing at cleaned-up temp directories; running in an environment where the session storage path was wiped (container restart, rm -rf of session dir).

Related errors


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