{"record":{"id":"b60741199ada7148","repo":"laurent22/joplin","slug":"cannot-move-item-with-type-itemtype","errorCode":null,"errorMessage":"Cannot move item with type ${itemType}","messagePattern":"Cannot move item with type (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.ts","lineNumber":58,"sourceCode":"\t\t\t\tshowFolder: (folder) => !itemIdToType.has(folder.id),\n\t\t\t});\n\n\t\t\t// It's important to allow the case where targetFolderId is the empty string,\n\t\t\t// since that corresponds to the toplevel notebook.\n\t\t\tif (targetFolderId !== null) {\n\t\t\t\ttry {\n\t\t\t\t\tfor (const id of itemIds) {\n\t\t\t\t\t\tif (id === targetFolderId) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst itemType = itemIdToType.get(id);\n\t\t\t\t\t\tif (itemType === ModelType.Note) {\n\t\t\t\t\t\t\tawait Note.moveToFolder(id, targetFolderId);\n\t\t\t\t\t\t} else if (itemType === ModelType.Folder) {\n\t\t\t\t\t\t\tawait Folder.moveToFolder(id, targetFolderId);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new Error(`Cannot move item with type ${itemType}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error('Error moving items', error);\n\t\t\t\t\tvoid shim.showMessageBox(`Error: ${error}`);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tenabledCondition: 'someNotesSelected && !noteIsReadOnlyShare',\n\t};\n};\n","sourceCodeStart":40,"sourceCodeEnd":70,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-desktop/gui/WindowCommandsAndDialogs/commands/moveToFolder.ts#L40-L70","documentation":"Thrown by the moveToFolder command when an item being moved has a type_ that is neither ModelType.Note nor ModelType.Folder. The command dispatches per-type (Note.moveToFolder / Folder.moveToFolder); any other item type (resource, tag, etc.) has no move semantics and is rejected.","triggerScenarios":"The user (or a script) selects a mix of items including at least one non-note/non-folder (e.g. a resource or a tag) and triggers move. itemIdToType.get(id) returns a ModelType value that falls through both branches to the else.","commonSituations":"Multi-select in a view that includes resources or other item types alongside notes/folders; a plugin constructs itemIds from a heterogeneous list; the type map was built incorrectly and reports a stale or wrong type for an ID.","solutions":["Filter the selection to only Note and Folder items before invoking move.","Verify itemIdToType is populated correctly for every selected ID.","Skip unsupported item types with a warning instead of aborting the whole move.","In the UI, disable the move action when the selection contains non-movable types."],"exampleFix":"// before\n} else {\n  throw new Error(`Cannot move item with type ${itemType}`);\n}\n\n// after — skip unsupported types, log, continue\n} else {\n  logger.warn(`Skipping item ${id}: cannot move type ${itemType}`);\n  continue;\n}","handlingStrategy":"validation","validationCode":"const movableIds = itemIds.filter(id => {\n  const t = itemIdToType.get(id);\n  return t === ModelType.Note || t === ModelType.Folder;\n});\n// pass only movableIds to the move loop","typeGuard":"function isMovableType(type: ModelType): boolean {\n  return type === ModelType.Note || type === ModelType.Folder;\n}","tryCatchPattern":"try {\n  await moveToFolderRuntime.execute(ctx, itemIds, targetFolderId);\n} catch (e) {\n  if (e.message.startsWith('Cannot move item with type')) {\n    // filter the selection to notes/folders and retry\n  } else throw e;\n}","preventionTips":["Build itemIdToType accurately from the current selection.","Filter selections to Note/Folder before enabling the move action.","Skip unsupported types with a warning instead of aborting the whole batch."],"tags":["desktop","move","notebook","validation","type-dispatch"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}