{"record":{"id":"10d2effa8d3b71e6","repo":"slidevjs/slidev","slug":"multiple-projects-found-for-entry-entry-pleas","errorCode":null,"errorMessage":"Multiple projects found for entry: ${entry}. Please specify the full path. All entries: ${formatList(projects.keys())}","messagePattern":"Multiple projects found for entry: (.+?)\\. Please specify the full path\\. All entries: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vscode/src/lmTools.ts","lineNumber":128,"sourceCode":"}\n\nfunction resolveProjectFromEntry(entry: string) {\n  if (entry === '' || entry === '$ACTIVE_SLIDE_ENTRY') {\n    if (!activeEntry.value) {\n      throw new Error('No active slide entry found. Please set an active slide entry before using this tool.')\n    }\n    entry = activeEntry.value\n  }\n\n  let project = projects.get(entry)\n  if (!project) {\n    entry = slash(entry)\n    const possibleProjects = [...projects.values()].filter(p => p.entry.includes(entry))\n    if (possibleProjects.length === 0) {\n      throw new Error(`No project found for entry: ${entry}. All entries: ${formatList(projects.keys())}`)\n    }\n    else if (possibleProjects.length > 1) {\n      throw new Error(`Multiple projects found for entry: ${entry}. Please specify the full path. All entries: ${formatList(projects.keys())}`)\n    }\n    else {\n      project = possibleProjects[0]\n    }\n  }\n\n  return project\n}\n\nfunction formatList(items: Iterable<string>): string {\n  const itemsArray = [...items]\n  if (itemsArray.length === 0) {\n    return 'No items found.'\n  }\n  return itemsArray.map(item => `- ${item}\\n`).join('')\n}\n\nfunction formatObject(obj: Record<string, string | number>): string {","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/slidevjs/slidev/blob/0d798ace5828966d9f77f62094d5f7a971ad98f7/packages/vscode/src/lmTools.ts#L110-L146","documentation":"Thrown by `resolveProjectFromEntry` in the 'more than one match' branch: the entry was not an exact key in `projects`, but the substring filter `p.entry.includes(entry)` matched two or more loaded projects. Because the resolver cannot pick deterministically, it refuses and lists all entries so the caller can disambiguate with a longer/absolute path.","triggerScenarios":"The model passes a short fragment (e.g. `'slides.md'`, `'deck'`) that is a substring of multiple loaded projects' entry paths. For example two decks both named `slides.md` in different folders, or a fragment like `slide` that appears in several absolute paths.","commonSituations":"A workspace with multiple Slidev decks, monorepo with several demo decks, or a fragment so short it is coincidentally present in several paths. The substring (not prefix/full-path) match is what makes short inputs ambiguous.","solutions":["Pass the full absolute entry path returned by `slidev_listEntries` so the substring matches exactly one project.","Lengthen the fragment until it is unique among loaded entries (e.g. include a parent directory name).","Use `slidev_chooseEntry` once with the full path to set `activeEntry`, then use `$ACTIVE_SLIDE_ENTRY` for subsequent calls."],"exampleFix":"// before: 'slides.md' matches two decks\n{ entrySlidePath: 'slides.md', slideNo: 1 } // throws [49]\n// after: disambiguate with the full path\n{ entrySlidePath: '/Users/me/talks/2026/slides.md', slideNo: 1 }","handlingStrategy":"validation","validationCode":"// Ensure the fragment is unambiguous before calling a tool:\nimport { slash } from '@antfu/utils'\nimport { projects } from './projects'\nfunction isUnambiguousEntry(fragment: string): boolean {\n  if (projects.has(fragment)) return true\n  const f = slash(fragment)\n  return [...projects.values()].filter(p => p.entry.includes(f)).length === 1\n}\n// if false, lengthen the fragment until exactly one project matches.","typeGuard":"function uniquelyMatches(fragment: string): boolean {\n  const f = slash(fragment)\n  const hits = [...projects.values()].filter(p => p.entry.includes(f))\n  return hits.length === 1\n}","tryCatchPattern":null,"preventionTips":["Pass the full absolute path instead of a short fragment when multiple decks coexist.","Use `slidev_listEntries` to compare candidate paths and pick a unique substring.","Set the active entry once with `slidev_chooseEntry` and then use `$ACTIVE_SLIDE_ENTRY` to avoid repeated disambiguation.","Avoid generic fragments like `slides.md` in multi-deck workspaces."],"tags":["slidev","vscode","language-model-tools","entry-resolution","ambiguous-match"],"backgroundTag":null,"analyzedSha":"0d798ace5828966d9f77f62094d5f7a971ad98f7","analyzedAt":"2026-08-12T17:10:56.221Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}