can1357/oh-my-pi · error

Documentation file not found: ${filename}${suffix}

Error message

Documentation file not found: ${filename}${suffix}

What it means

The requested documentation filename passed validation (relative, no traversal) but does not match any bundled doc file. The error appends up to 5 fuzzy 'Did you mean' suggestions when close matches exist, or a hint to use omp:// to list all files.

Source

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

		}

		const docPath =
			normalized === "docs" ? "" : normalized.startsWith("docs/") ? normalized.slice("docs/".length) : normalized;
		if (!docPath) {
			return this.#listDocs(url);
		}

		const content = await getEmbeddedDoc(docPath);
		if (content === undefined) {
			const lookup = docPath.replace(/\.md$/, "");
			const suggestions = getDocFilenames()
				.filter(f => f.includes(lookup) || lookup.includes(f.replace(/\.md$/, "")))
				.slice(0, 5);
			const suffix =
				suggestions.length > 0
					? `\nDid you mean: ${suggestions.join(", ")}`
					: "\nUse omp:// to list available files.";
			throw new Error(`Documentation file not found: ${filename}${suffix}`);
		}

		return {
			url: url.href,
			content,
			contentType: "text/markdown",
			size: Buffer.byteLength(content, "utf-8"),
		};
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the 'Did you mean' suffix in the error and use the suggested filename.
  2. Resolve omp:// (bare) to list all available documentation files, then pick the exact name.
  3. If a previously working doc name fails, check the changelog for renamed docs in the new version.

Example fix

// before
const doc = await router.resolve('omp://agents');
// after: list first, then resolve exact name
const list = await router.resolve('omp://');
const doc = await router.resolve('omp://agents.md');
Defensive patterns

Strategy: fallback

Validate before calling

const listing = await router.resolve('omp://'); // parse content lines to get valid names
const known = listing.content.match(/- \[(.+)\]/g) ?? [];
if (!known.some(k => k.includes(docName))) throw new Error(`unknown doc: ${docName}`);

Try / catch

try {
  return await router.resolve(`omp://${name}`);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Documentation file not found')) {
    const suggestion = /Did you mean: (.+)/.exec(err.message)?.[1];
    if (suggestion) return router.resolve(`omp://${suggestion.split(', ')[0].trim()}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Resolving omp://<name> where <name> (after stripping the optional 'docs/' prefix) is not among getDocFilenames(); partial names that fuzzy-match existing docs produce suggestions.

Common situations: Typos in doc names; guessing doc names instead of listing them; doc renamed between versions so an old reference no longer matches.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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