laurent22/joplin · error · Error
More than one item match "%s". Please narrow down your query
Error message
More than one item match "%s". Please narrow down your query.
What it means
App.loadItem wraps loadItems and, when more than one item matches the pattern, throws 'More than one item match' because the interactive multiple-choice disambiguation UI was commented out. The caller must supply a more specific pattern. The message is i18n-translated via _().
Source
Thrown at packages/app-cli/app/app.ts:67
type = ModelType.Folder;
pattern = pattern.substr(1);
}
return this.loadItem(type, pattern, options);
}
public async loadItem(type: FolderOrNoteType, pattern: string, options: { parent?: FolderEntity } | null = null) {
const output = await this.loadItems(type, pattern, options);
if (output.length > 1) {
// output.sort((a, b) => { return a.user_updated_time < b.user_updated_time ? +1 : -1; });
// let answers = { 0: _('[Cancel]') };
// for (let i = 0; i < output.length; i++) {
// answers[i + 1] = output[i].title;
// }
// Not really useful with new UI?
throw new Error(_('More than one item match "%s". Please narrow down your query.', pattern));
// let msg = _('More than one item match "%s". Please select one:', pattern);
// const response = await cliUtils.promptMcq(msg, answers);
// if (!response) return null;
// return output[response - 1];
} else {
return output.length ? output[0] : null;
}
}
public async loadItemOrFail(type: FolderOrNoteType, pattern: string) {
const output = await this.loadItem(type, pattern);
if (!output) throw new Error(_('Cannot find "%s".', pattern));
return output;
}
public async loadItems(type: FolderOrNoteType, pattern: string, options: { parent?: FolderEntity } | null = null): Promise<(FolderEntity | NoteEntity)[]> {View on GitHub (pinned to 2654b33620)
Solutions
- Use the full, unique title or the complete item id.
- Select the specific notebook first with 'use <notebook>' to scope title lookups.
- Rename one of the duplicates so the title is unique.
- Use a longer partial id (loadByPartialId requires length >= 2 but longer prefixes are more unique).
Example fix
// before
// const item = await app().loadItem(ModelType.Note, 'test'); // throws if >1 match
// after
// const items = await app().loadItems(ModelType.Note, 'test');
// if (items.length > 1) {
// // disambiguate: list matches and pick by full id
// const chosen = items[0]; // user selects
// } Defensive patterns
Strategy: validation
Validate before calling
const items = await app().loadItems(type, pattern, options);
if (items.length > 1) {
// surface the matches so the user can pick a unique title/id
throw new Error(`Multiple matches: ${items.map(i => i.title).join(', ')}`);
} Try / catch
try {
const item = await app().loadItem(type, pattern);
} catch (e) {
if (/More than one item match/.test(e.message)) {
// list candidates and re-prompt with a more specific pattern
}
} Prevention
- Prefer full item ids over titles in scripts.
- Scope lookups to a specific notebook before matching by title.
- Keep note titles unique within a notebook.
When it happens
Trigger: Two or more notes (or notebooks) share a matching title, or a short partial id prefix matches multiple rows; e.g. running 'cat test' when several notes are titled 'test', or a 2-character id prefix that is non-unique.
Common situations: Duplicate note titles in the same notebook; short partial ids; wildcard-like patterns that expand to many matches; bulk-imported data with repeated names.
Related errors
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/40def4323f7dbbcd.
Report an issue: GitHub.