{"record":{"id":"b31b34ba1f8d7a51","repo":"can1357/oh-my-pi","slug":"documentation-file-not-found-filename-suffix","errorCode":null,"errorMessage":"Documentation file not found: ${filename}${suffix}","messagePattern":"Documentation file not found: (.+?)(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/omp-protocol.ts","lineNumber":84,"sourceCode":"\t\t}\n\n\t\tconst docPath =\n\t\t\tnormalized === \"docs\" ? \"\" : normalized.startsWith(\"docs/\") ? normalized.slice(\"docs/\".length) : normalized;\n\t\tif (!docPath) {\n\t\t\treturn this.#listDocs(url);\n\t\t}\n\n\t\tconst content = await getEmbeddedDoc(docPath);\n\t\tif (content === undefined) {\n\t\t\tconst lookup = docPath.replace(/\\.md$/, \"\");\n\t\t\tconst suggestions = getDocFilenames()\n\t\t\t\t.filter(f => f.includes(lookup) || lookup.includes(f.replace(/\\.md$/, \"\")))\n\t\t\t\t.slice(0, 5);\n\t\t\tconst suffix =\n\t\t\t\tsuggestions.length > 0\n\t\t\t\t\t? `\\nDid you mean: ${suggestions.join(\", \")}`\n\t\t\t\t\t: \"\\nUse omp:// to list available files.\";\n\t\t\tthrow new Error(`Documentation file not found: ${filename}${suffix}`);\n\t\t}\n\n\t\treturn {\n\t\t\turl: url.href,\n\t\t\tcontent,\n\t\t\tcontentType: \"text/markdown\",\n\t\t\tsize: Buffer.byteLength(content, \"utf-8\"),\n\t\t};\n\t}\n}\n","sourceCodeStart":66,"sourceCodeEnd":95,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/omp-protocol.ts#L66-L95","documentation":"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.","triggerScenarios":"Resolving omp://<name> where <name> (after stripping the optional 'docs/' prefix) is not among getDocFilenames(); partial names that fuzzy-match existing docs produce suggestions.","commonSituations":"Typos in doc names; guessing doc names instead of listing them; doc renamed between versions so an old reference no longer matches.","solutions":["Read the 'Did you mean' suffix in the error and use the suggested filename.","Resolve omp:// (bare) to list all available documentation files, then pick the exact name.","If a previously working doc name fails, check the changelog for renamed docs in the new version."],"exampleFix":"// before\nconst doc = await router.resolve('omp://agents');\n// after: list first, then resolve exact name\nconst list = await router.resolve('omp://');\nconst doc = await router.resolve('omp://agents.md');","handlingStrategy":"fallback","validationCode":"const listing = await router.resolve('omp://'); // parse content lines to get valid names\nconst known = listing.content.match(/- \\[(.+)\\]/g) ?? [];\nif (!known.some(k => k.includes(docName))) throw new Error(`unknown doc: ${docName}`);","typeGuard":null,"tryCatchPattern":"try {\n  return await router.resolve(`omp://${name}`);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Documentation file not found')) {\n    const suggestion = /Did you mean: (.+)/.exec(err.message)?.[1];\n    if (suggestion) return router.resolve(`omp://${suggestion.split(', ')[0].trim()}`);\n  }\n  throw err;\n}","preventionTips":["Resolve omp:// first to enumerate valid doc filenames.","Read and act on the 'Did you mean' suggestions embedded in the error.","Update stored doc references when upgrading across versions with renamed docs."],"tags":["documentation","internal-url","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}