{"record":{"id":"a04431fff953d5a1","repo":"laurent22/joplin","slug":"cannot-find-s-a04431","errorCode":null,"errorMessage":"Cannot find \"%s\".","messagePattern":"Cannot find \"(.+?)\"\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-cli/app/command-tag.ts","lineNumber":37,"sourceCode":"\t\treturn [['-l, --long', _('Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE')]];\n\t}\n\n\tpublic override async action(args: { 'tag-command': string; tag?: string; note?: string; options: { long?: boolean } }) {\n\t\tlet tag: TagEntity | null = null;\n\t\tconst options = args.options;\n\n\t\t// app.loadItem's parameter type is narrower (Note | Folder | 'folderOrNote') than the\n\t\t// runtime support, which falls through to BaseItem.itemClass(type).loadByTitle for other\n\t\t// types. ModelType.Tag is one of those — cast to satisfy the type checker.\n\t\tif (args.tag) tag = await app().loadItem(ModelType.Tag as ModelType.Note, args.tag);\n\t\tlet notes: NoteEntity[] = [];\n\t\tif (args.note) {\n\t\t\tnotes = await app().loadItems(ModelType.Note, args.note);\n\t\t}\n\n\t\tconst command = args['tag-command'];\n\n\t\tif (command === 'remove' && !tag) throw new Error(_('Cannot find \"%s\".', args.tag));\n\n\t\tif (command === 'add') {\n\t\t\tif (!notes.length) throw new Error(_('Cannot find \"%s\".', args.note));\n\t\t\tif (!tag) tag = await Tag.save({ title: args.tag }, { userSideValidation: true });\n\t\t\tfor (let i = 0; i < notes.length; i++) {\n\t\t\t\tawait Tag.addNote(tag.id, notes[i].id);\n\t\t\t}\n\t\t} else if (command === 'remove') {\n\t\t\tif (!tag) throw new Error(_('Cannot find \"%s\".', args.tag));\n\t\t\tif (!notes.length) throw new Error(_('Cannot find \"%s\".', args.note));\n\t\t\tfor (let i = 0; i < notes.length; i++) {\n\t\t\t\tawait Tag.removeNote(tag.id, notes[i].id);\n\t\t\t}\n\t\t} else if (command === 'list') {\n\t\t\tif (tag) {\n\t\t\t\tconst notes: NoteEntity[] = await Tag.notes(tag.id);\n\t\t\t\tnotes.map(note => {\n\t\t\t\t\tlet line = '';","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-cli/app/command-tag.ts#L19-L55","documentation":"Thrown by the `tag` command when `tag-command === 'remove'` and the tag specified by `args.tag` could not be loaded (the earlier `app().loadItem(ModelType.Tag, ...)` returned null). The check runs before the add/remove branches so that a non-existent tag aborts removal early. `%s` is replaced with the requested tag title.","triggerScenarios":"Running `:tag remove <tag> [<note>]` where `<tag>` does not match any Tag.title in the database. Because removal requires an existing tag, a missing tag is a hard error rather than a no-op.","commonSituations":"Typo in the tag name; tag was renamed or deleted; referencing a tag from another profile; tags not yet synced from the server.","solutions":["List tags with `:tag list` to confirm the exact title and retry.","Sync first if the tag may exist only on another device.","If you only want to ensure the tag is gone, the error confirms it is — no further action needed."],"exampleFix":"// before\nif (command === 'remove' && !tag) throw new Error(_('Cannot find \"%s\".', args.tag));\n\n// after - hint at available tags\nif (command === 'remove' && !tag) throw new Error(_('Cannot find tag \"%s\". Run \\`tag list\\` to see existing tags.', args.tag));","handlingStrategy":"validation","validationCode":"const tag = await app().loadItem(ModelType.Tag as ModelType.Note, tagName);\nif (subcommand === 'remove' && !tag) {\n\tthrow new Error(`Tag \"${tagName}\" not found. Run \\`tag list\\`.`);\n}","typeGuard":"const isExistingTag = (t: TagEntity | null): t is TagEntity => t !== null;","tryCatchPattern":"try {\n\tawait app().executeCommand(['tag', 'remove', tagName, noteTitle]);\n} catch (e) {\n\tif (/Cannot find/.test(e.message) && /* tag context */) { /* re-list tags */ }\n\telse throw e;\n}","preventionTips":["List tags before removing one to copy the exact title.","Sync first if the tag may exist only on another device.","For removal, an error here means the tag is already gone — treat as success."],"tags":["tag","remove","cli","not-found"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}