laurent22/joplin · error · Error
Cannot find "%s".
Error message
Cannot find "%s".
What it means
Thrown by `restore <pattern>` when `app().loadItems('folderOrNote', pattern)` returns an empty array. loadItems('folderOrNote', ...) tries folders then notes by exact title, full id, partial id >=2 chars. The command then calls `restoreItems(items[0].type_, ids, { useRestoreFolder: true })`. If the pattern matches nothing in the trash (or nothing at all), the array is empty.
Source
Thrown at packages/app-cli/app/command-restore.ts:19
import BaseCommand from './base-command';
import app from './app';
import { _ } from '@joplin/lib/locale';
import restoreItems from '@joplin/lib/services/trash/restoreItems';
class Command extends BaseCommand {
public override usage() {
return 'restore <pattern>';
}
public override description() {
return _('Restore the items matching <pattern> from the trash.');
}
public override async action(args: { pattern: string }) {
const pattern = args['pattern'];
const items = await app().loadItems('folderOrNote', pattern);
if (!items.length) throw new Error(_('Cannot find "%s".', pattern));
const ids = items.map(n => n.id);
await restoreItems(items[0].type_, ids, { useRestoreFolder: true });
}
}
module.exports = Command;
View on GitHub (pinned to 2654b33620)
Solutions
- List trash contents (in the GUI, or query the `notes`/`folders` tables where `deleted_time > 0`) to find exact titles/ids
- Use the full or short id of the trashed item
- Confirm the item is actually in trash and not already permanently purged
Example fix
// before joplin restore "Old Note" // throws if not in trash or typo // after # find the trashed item's id (GUI trash view, or DB query), then: joplin restore <note-id>
Defensive patterns
Strategy: validation
Validate before calling
import app from './app';
async function resolveTrashItems(pattern: string) {
const items = await app().loadItems('folderOrNote', pattern);
if (!items.length) throw new Error(`Cannot find "${pattern}" in trash. Verify trash contents or use the id.`);
// sanity: caller should only feed actually-deleted items
const allTrashed = items.every(i => !!(i as any).deleted_time);
if (!allTrashed) throw new Error('Some matched items are not in trash.');
return items;
} Type guard
const isTrashCandidate = (i: any): boolean => !!i?.id && typeof i.deleted_time === 'number' && i.deleted_time > 0;
Prevention
- Confirm items are actually in trash before calling restore
- Use full ids for trashed items (titles may collide with live items)
- Watch trash retention settings — purged items cannot be restored
When it happens
Trigger: Pattern matches no trashed item; typo; partial id <2 chars; item was never deleted (so it isn't in trash); item already purged from trash by the revision/trash retention.
Common situations: Trying to restore by a title that exists only as a live (non-deleted) item; trash auto-emptyed; wrong partial id.
Related errors
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/34b9f74ef726dd92.
Report an issue: GitHub.