{"record":{"id":"9a1b96526f781d28","repo":"can1357/oh-my-pi","slug":"no-artifacts-directory-found-9a1b96","errorCode":null,"errorMessage":"No artifacts directory found","messagePattern":"No artifacts directory found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/artifact-protocol.ts","lineNumber":82,"sourceCode":"\t\t\tfiles = await fs.readdir(dir);\n\t\t\tanyDirExists = true;\n\t\t} catch (err) {\n\t\t\tif (isEnoent(err)) continue;\n\t\t\tthrow err;\n\t\t}\n\t\tconst match = files.find(f => f.startsWith(`${id}.`));\n\t\tif (match) {\n\t\t\tfoundPath = path.join(dir, match);\n\t\t\tbreak;\n\t\t}\n\t\tfor (const f of files) {\n\t\t\tconst m = f.match(/^(\\d+)\\./);\n\t\t\tif (m) availableIds.add(m[1]);\n\t\t}\n\t}\n\n\tif (!anyDirExists) {\n\t\tthrow new Error(\"No artifacts directory found\");\n\t}\n\n\tif (!foundPath) {\n\t\tconst sorted = [...availableIds].sort((a, b) => Number(a) - Number(b));\n\t\tconst availableStr = sorted.length > 0 ? sorted.join(\", \") : \"none\";\n\t\tthrow new Error(`Artifact ${id} not found. Available: ${availableStr}`);\n\t}\n\n\tconst stat = await Bun.file(foundPath).stat();\n\tif (stat.isDirectory()) {\n\t\tthrow new Error(`Artifact ${id} resolved to a directory, not a file`);\n\t}\n\treturn { id, path: foundPath, size: stat.size };\n}\n\nexport class ArtifactProtocolHandler implements ProtocolHandler {\n\treadonly scheme = \"artifact\";\n\treadonly immutable = true;","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/artifact-protocol.ts#L64-L100","documentation":"resolveArtifactFile (packages/coding-agent/src/internal-urls/artifact-protocol.ts:82) throws when at least one session is registered, but none of the candidate artifacts directories exists on disk (every fs.readdir hit ENOENT). The registry references directories that were never created or have been deleted.","triggerScenarios":"Resolving any artifact:// URL when all registered session artifacts dirs are missing: a fresh session that has not yet written its first artifact, a deleted/stale session directory still listed in the persisted roster, or an artifacts dir path configured to a removed location.","commonSituations":"Pointing artifact tools at a session before any artifact was produced; cleaning artifacts dirs manually while old sessions remain in the roster; moving/copying session data without the artifacts subdirectories; different machine/container where session paths don't exist.","solutions":["Produce at least one artifact in the session so its artifacts directory is created, then retry.","Verify the expected artifacts directory exists (session file path minus .jsonl suffix) and recreate it if it was deleted.","Prune stale sessions from the persisted roster/AgentRegistry so dead dirs aren't scanned.","Correct any misconfigured session/artifacts path pointing at a location that was removed or mounted elsewhere."],"exampleFix":"// before\nconst res = await resolveArtifactFile(new URL(\"artifact://0\")); // dir never created\n// after\nimport * as fs from \"node:fs/promises\";\nawait fs.mkdir(artifactsDir, { recursive: true }); // ensure session dir exists\nconst res = await resolveArtifactFile(new URL(\"artifact://0\"));","handlingStrategy":"validation","validationCode":"import * as fs from \"node:fs/promises\";\nimport { artifactsDirsFromRegistry } from \"./registry-helpers\";\nconst dirs = artifactsDirsFromRegistry();\nconst ok = await Promise.all(dirs.map(d => fs.access(d).then(() => true, () => false)));\nif (!ok.some(Boolean)) {\n  await fs.mkdir(dirs[0], { recursive: true }); // or report: no artifacts directory exists\n}","typeGuard":"function dirExists(p: string): boolean {\n  try { return require(\"node:fs\").statSync(p).isDirectory(); } catch { return false; }\n}","tryCatchPattern":"try {\n  const res = await resolveArtifactFile(url, context);\n} catch (err) {\n  if (err instanceof Error && err.message === \"No artifacts directory found\") {\n    // session has produced no artifacts dir; create it or inform user\n  } else throw err;\n}","preventionTips":["Create the session artifacts directory when the session starts, before any artifact reads.","Prune stale roster entries whose session directories no longer exist.","When copying/moving session data, include the artifacts subdirectories.","Check directory existence once at session attach rather than per-URL."],"tags":["filesystem","internal-urls","artifact-protocol","missing-directory"],"backgroundTag":"directory-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}