slidevjs/slidev · error · Error

Multiple projects found for entry: ${entry}. Please specify

Error message

Multiple projects found for entry: ${entry}. Please specify the full path. All entries: ${formatList(projects.keys())}

What it means

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.

Source

Thrown at packages/vscode/src/lmTools.ts:128

}

function resolveProjectFromEntry(entry: string) {
  if (entry === '' || entry === '$ACTIVE_SLIDE_ENTRY') {
    if (!activeEntry.value) {
      throw new Error('No active slide entry found. Please set an active slide entry before using this tool.')
    }
    entry = activeEntry.value
  }

  let project = projects.get(entry)
  if (!project) {
    entry = slash(entry)
    const possibleProjects = [...projects.values()].filter(p => p.entry.includes(entry))
    if (possibleProjects.length === 0) {
      throw new Error(`No project found for entry: ${entry}. All entries: ${formatList(projects.keys())}`)
    }
    else if (possibleProjects.length > 1) {
      throw new Error(`Multiple projects found for entry: ${entry}. Please specify the full path. All entries: ${formatList(projects.keys())}`)
    }
    else {
      project = possibleProjects[0]
    }
  }

  return project
}

function formatList(items: Iterable<string>): string {
  const itemsArray = [...items]
  if (itemsArray.length === 0) {
    return 'No items found.'
  }
  return itemsArray.map(item => `- ${item}\n`).join('')
}

function formatObject(obj: Record<string, string | number>): string {

View on GitHub (pinned to 0d798ace58)

Solutions

  1. Pass the full absolute entry path returned by `slidev_listEntries` so the substring matches exactly one project.
  2. Lengthen the fragment until it is unique among loaded entries (e.g. include a parent directory name).
  3. Use `slidev_chooseEntry` once with the full path to set `activeEntry`, then use `$ACTIVE_SLIDE_ENTRY` for subsequent calls.

Example fix

// before: 'slides.md' matches two decks
{ entrySlidePath: 'slides.md', slideNo: 1 } // throws [49]
// after: disambiguate with the full path
{ entrySlidePath: '/Users/me/talks/2026/slides.md', slideNo: 1 }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the fragment is unambiguous before calling a tool:
import { slash } from '@antfu/utils'
import { projects } from './projects'
function isUnambiguousEntry(fragment: string): boolean {
  if (projects.has(fragment)) return true
  const f = slash(fragment)
  return [...projects.values()].filter(p => p.entry.includes(f)).length === 1
}
// if false, lengthen the fragment until exactly one project matches.

Type guard

function uniquelyMatches(fragment: string): boolean {
  const f = slash(fragment)
  const hits = [...projects.values()].filter(p => p.entry.includes(f))
  return hits.length === 1
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of slidevjs/slidev@0d798ace58 (2026-08-12). Data as JSON: /api/errors/10d2effa8d3b71e6. Report an issue: GitHub.