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

  1. Use the full, unique title or the complete item id.
  2. Select the specific notebook first with 'use <notebook>' to scope title lookups.
  3. Rename one of the duplicates so the title is unique.
  4. 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

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.