{"record":{"id":"550efc2504d6501c","repo":"laurent22/joplin","slug":"cannot-find-s-550efc","errorCode":null,"errorMessage":"Cannot find \"%s\".","messagePattern":"Cannot find \"(.+?)\"\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-cli/app/command-todo.ts","lineNumber":22,"sourceCode":"import { ModelType } from '@joplin/lib/BaseModel';\nimport Note from '@joplin/lib/models/Note';\nimport time from '@joplin/lib/time';\nimport { NoteEntity } from '@joplin/lib/services/database/types';\n\nclass Command extends BaseCommand {\n\tpublic override usage() {\n\t\treturn 'todo <todo-command> <note-pattern>';\n\t}\n\n\tpublic override description() {\n\t\treturn _('<todo-command> can either be \"toggle\" or \"clear\". Use \"toggle\" to toggle the given to-do between completed and uncompleted state (If the target is a regular note it will be converted to a to-do). Use \"clear\" to convert the to-do back to a regular note.');\n\t}\n\n\tpublic override async action(args: { 'todo-command': string; 'note-pattern': string }) {\n\t\tconst action = args['todo-command'];\n\t\tconst pattern = args['note-pattern'];\n\t\tconst notes: NoteEntity[] = await app().loadItems(ModelType.Note, pattern);\n\t\tif (!notes.length) throw new Error(_('Cannot find \"%s\".', pattern));\n\n\t\tfor (let i = 0; i < notes.length; i++) {\n\t\t\tconst note = notes[i];\n\n\t\t\tthis.encryptionCheck(note);\n\n\t\t\tlet toSave: NoteEntity = {\n\t\t\t\tid: note.id,\n\t\t\t};\n\n\t\t\tif (action === 'toggle') {\n\t\t\t\tif (!note.is_todo) {\n\t\t\t\t\ttoSave = Note.toggleIsTodo(note);\n\t\t\t\t} else {\n\t\t\t\t\ttoSave.todo_completed = note.todo_completed ? 0 : time.unixMs();\n\t\t\t\t}\n\t\t\t} else if (action === 'clear') {\n\t\t\t\ttoSave.is_todo = 0;","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-cli/app/command-todo.ts#L4-L40","documentation":"Thrown by the `todo` CLI command when the note-pattern argument does not match any note in the database. The command calls app().loadItems(ModelType.Note, pattern) and checks that the returned array is non-empty before proceeding; an empty result means no note matched the glob/regex pattern supplied on the command line.","triggerScenarios":"Running `todo toggle <pattern>` or `todo clear <pattern>` where <pattern> matches zero notes. The match is delegated to app().loadItems which applies the pattern against note titles/IDs; any pattern yielding no hits triggers this.","commonSituations":"Typo in the note pattern, referencing a note by an old title after a rename, the note existing in a different notebook/sync target, or quoting a pattern with shell special characters that get mangled.","solutions":["Run `ls` (the note-list CLI command) with the same pattern to confirm what matches, then adjust the pattern.","Verify the note title spelling and case against the database.","Try the note's ID instead of a title substring as the pattern.","Ensure the CLI is pointed at the correct profile/database (JOPLIN_PROFILE / --profile)."],"exampleFix":"// before\nconst notes = await app().loadItems(ModelType.Note, pattern);\nif (!notes.length) throw new Error(_('Cannot find \"%s\".', pattern));\n\n// after — surface the count and hint\nconst notes = await app().loadItems(ModelType.Note, pattern);\nif (!notes.length) throw new Error(_('Cannot find \"%s\". Run `ls <pattern>` to list matching notes.', pattern));","handlingStrategy":"validation","validationCode":"// Before invoking the todo command, confirm the pattern matches.\nconst notes = await app().loadItems(ModelType.Note, pattern);\nif (notes.length === 0) {\n  console.error(`No notes match \"${pattern}\". Aborting.`);\n  return;\n}\n// safe to proceed with toggle/clear","typeGuard":"function patternHasMatches(notes: NoteEntity[]): boolean {\n  return Array.isArray(notes) && notes.length > 0;\n}","tryCatchPattern":"try {\n  await command.exec(['todo', 'toggle', pattern]);\n} catch (e) {\n  if (e.message.startsWith('Cannot find')) {\n    // pattern matched nothing — surface to user, do not retry blindly\n  } else throw e;\n}","preventionTips":["Always verify a pattern matches via `ls <pattern>` before running todo on it.","Prefer note IDs over title substrings to avoid ambiguous/empty matches.","Quote shell arguments to prevent glob expansion corrupting the pattern."],"tags":["cli","note-lookup","validation","user-input"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}