{"record":{"id":"4c980dcfc3a9149c","repo":"laurent22/joplin","slug":"ambiguous-notebook-s-please-use-notebook-id-in","errorCode":null,"errorMessage":"Ambiguous notebook \"%s\". Please use notebook id instead - press \"ti\" to see the short notebook id or use $b for current selected notebook","messagePattern":"Ambiguous notebook \"(.+?)\"\\. Please use notebook id instead - press \"ti\" to see the short notebook id or use \\$b for current selected notebook","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-cli/app/command-mv.ts","lineNumber":36,"sourceCode":"\t\tconst pattern = args['item'];\n\t\tconst destination = args['notebook'];\n\t\tlet folder = null;\n\n\t\tif (destination !== 'root') {\n\t\t\tfolder = await app().loadItem(ModelType.Folder, destination);\n\t\t\tif (!folder) throw new Error(_('Cannot find \"%s\".', destination));\n\t\t}\n\n\t\tconst destinationDuplicates = await Folder.search({ titlePattern: destination, limit: 2 });\n\t\tif (destinationDuplicates.length > 1) {\n\t\t\tthrow new Error(_('Ambiguous notebook \"%s\". Please use short notebook id instead - press \"ti\" to see the short notebook id', destination));\n\t\t}\n\n\t\tconst itemFolder = await app().loadItem(ModelType.Folder, pattern);\n\t\tif (itemFolder) {\n\t\t\tconst sourceDuplicates = await Folder.search({ titlePattern: pattern, limit: 2 });\n\t\t\tif (sourceDuplicates.length > 1) {\n\t\t\t\tthrow new Error(_('Ambiguous notebook \"%s\". Please use notebook id instead - press \"ti\" to see the short notebook id or use $b for current selected notebook', pattern));\n\t\t\t}\n\t\t\tif (destination === 'root') {\n\t\t\t\tawait Folder.moveToFolder(itemFolder.id, '');\n\t\t\t} else {\n\t\t\t\tawait Folder.moveToFolder(itemFolder.id, folder.id);\n\t\t\t}\n\t\t} else {\n\t\t\tconst notes = await app().loadItems(ModelType.Note, pattern);\n\t\t\tif (notes.length === 0) throw new Error(_('Cannot find \"%s\".', pattern));\n\t\t\tfor (let i = 0; i < notes.length; i++) {\n\t\t\t\tawait Note.moveToFolder(notes[i].id, folder.id);\n\t\t\t}\n\t\t}\n\t}\n}\n\nmodule.exports = Command;\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-cli/app/command-mv.ts#L18-L54","documentation":"Thrown by `mv <item> <notebook>` when the *source* pattern resolved to a folder (`itemFolder` truthy) but `Folder.search({ titlePattern: pattern, limit: 2 })` returns >1 row. Message differs from the destination-ambiguous message: it suggests `$b` for the currently selected notebook, because the source is the item being moved (where the current notebook shortcut is more relevant).","triggerScenarios":"Moving a notebook whose name LIKE-matches other notebooks; source pattern is a short substring common to multiple folders.","commonSituations":"Reorganizing a flat tree with many similarly-named notebooks; scripting moves by partial names.","solutions":["Use the notebook id of the source: `joplin mv <short-id> <destination>`","Use `$b` for the currently selected notebook: `joplin mv $b <destination>` (works in interactive mode)","Rename the source notebook to a unique title first"],"exampleFix":"// before\njoplin mv Note Projects   // \"Note\" LIKE-matches \"Notes\" and \"Notebook\" -> throws\n\n// after\njoplin mv 7f3a Projects    # by short id\n# or in interactive mode, with the source notebook selected:\n:mv $b Projects","handlingStrategy":"validation","validationCode":"import Folder from '@joplin/lib/models/Folder';\n\nasync function assertSourceNotebookUnambiguous(pattern: string) {\n  const dups = await Folder.search({ titlePattern: pattern, limit: 2 });\n  if (dups.length > 1) {\n    throw new Error(`Source notebook \"${pattern}\" is ambiguous. Use its id, or $b for the current notebook.`);\n  }\n}","typeGuard":"const isUnambiguousSource = async (ref: string): Promise<boolean> =>\n  (await Folder.search({ titlePattern: ref, limit: 2 })).length <= 1;","tryCatchPattern":null,"preventionTips":["Use `$b` in interactive mode to refer to the currently selected notebook as the source","Pass notebook ids when scripting moves","Rename ambiguous source notebooks before bulk reorganization"],"tags":["cli","mv","notebook-lookup","ambiguous","validation"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}