laurent22/joplin · error · Error
Cannot find "%s".
Error message
Cannot find "%s".
What it means
Thrown by `import <path> [notebook]` when a notebook argument was supplied (`args.notebook` truthy) but `app().loadItem(ModelType.Folder, args.notebook)` returned null. The guard is `if (args.notebook && !destinationFolder)`, so omitting the notebook arg entirely falls through to `Folder.defaultFolder()` instead of throwing. Lookup is global (not parent-scoped) for folders.
Source
Thrown at packages/app-cli/app/command-import.ts:37
public override options() {
const service = InteropService.instance();
const formats = service
.modules()
.filter(m => m.type === 'importer')
.map(m => m.format);
return [
['--format <format>', _('Source format: %s', ['auto'].concat(unique(formats)).join(', '))],
['-f, --force', _('Do not ask for confirmation.')],
['--output-format <output-format>', _('Output format: %s', 'md, html')],
];
}
public override async action(args: { path: string; 'notebook'?: string; options: { format?: string; outputFormat?: string } }) {
let destinationFolder = await app().loadItem(ModelType.Folder, args.notebook);
if (args.notebook && !destinationFolder) throw new Error(_('Cannot find "%s".', args.notebook));
if (!destinationFolder) destinationFolder = await Folder.defaultFolder();
const importOptions: ImportOptions = {};
importOptions.path = args.path;
importOptions.format = args.options.format ? args.options.format : 'auto';
importOptions.destinationFolderId = destinationFolder ? destinationFolder.id : null;
let lastProgress = '';
// onProgress/onError supported by Enex import only
importOptions.onProgress = progressState => {
const line = [];
line.push(_('Found: %d.', progressState.loaded));
line.push(_('Created: %d.', progressState.created));
if (progressState.updated) line.push(_('Updated: %d.', progressState.updated));
if (progressState.skipped) line.push(_('Skipped: %d.', progressState.skipped));View on GitHub (pinned to 2654b33620)
Solutions
- Create the destination notebook first: `joplin mkbook <name>`, then re-run import with that name
- Omit the notebook argument entirely to import into the most recently created notebook (Folder.defaultFolder ordering)
- Verify the title with `joplin ls /` or use the short notebook id
Example fix
// before joplin import notes.enex Incoming // throws if "Incoming" doesn't exist // after joplin mkbook Incoming joplin import notes.enex Incoming // or omit notebook to use default: joplin import notes.enex
Defensive patterns
Strategy: validation
Validate before calling
import app from './app';
import Folder from '@joplin/lib/models/Folder';
import { ModelType } from '@joplin/lib/BaseModel';
async function resolveImportDestination(notebookRef?: string) {
if (!notebookRef) {
const def = await Folder.defaultFolder();
if (!def) throw new Error('No notebooks exist. Run `mkbook <name>` before importing.');
return def;
}
const folder = await app().loadItem(ModelType.Folder, notebookRef);
if (!folder) throw new Error(`Cannot find notebook "${notebookRef}". Create it with \`mkbook\` first.`);
return folder;
} Type guard
const isFolder = (f: any): f is { id: string; title: string } =>
!!f && typeof f.id === 'string'; Prevention
- Pre-create import target notebooks with `mkbook`
- Omit the notebook arg to fall back to defaultFolder() when you don't care
- Verify with `ls /` before scripted imports
When it happens
Trigger: Passing a notebook name that doesn't exist; typo; partial id <2 chars; expecting import to auto-create the destination notebook (it does not).
Common situations: First-time import workflow where the user assumes the destination notebook is created on demand; renamed target notebook; copy-paste error in scripts.
Related errors
- Cannot find: "%s"
- Ambiguous notebook "%s". Please use short notebook id instea
- Cannot find "%s".
- Ambiguous notebook "%s". Please use short notebook id instea
- Ambiguous notebook "%s". Please use notebook id instead - pr
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/54d3fd85329cdd48.
Report an issue: GitHub.