{"record":{"id":"34b34a4a9e237353","repo":"laurent22/joplin","slug":"no-such-folder-folderid","errorCode":null,"errorMessage":"No such folder: ${folderId}","messagePattern":"No such folder: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lib/services/share/ShareService.ts","lineNumber":327,"sourceCode":"\t}\n\n\tpublic async publishFolder(folderId: string): Promise<StateShare> {\n\t\tconst folder = await Folder.load(folderId);\n\t\tif (!folder) throw new Error(`No such folder: ${folderId}`);\n\n\t\tconst share = await this.api().exec('POST', 'api/shares', {}, {\n\t\t\tfolder_id: folderId,\n\t\t\ttype: ShareType.PublishedFolder,\n\t\t});\n\n\t\tawait this.refreshShares();\n\n\t\treturn share;\n\t}\n\n\tpublic async unpublishFolder(folderId: string): Promise<void> {\n\t\tconst folder = await Folder.load(folderId);\n\t\tif (!folder) throw new Error(`No such folder: ${folderId}`);\n\n\t\tconst share = this.shares.find(s => s.type === ShareType.PublishedFolder && s.folder_id === folderId);\n\t\tif (!share) throw new Error(`No published share for folder: ${folderId}`);\n\n\t\tconst remainingShares = this.shares.filter(s => s.id !== share.id);\n\t\tconst folderIds = [folderId, ...(await Folder.allChildrenFolders(folderId)).map(f => f.id)];\n\t\tconst folders = await Folder.loadItemsByIds(folderIds) as FolderEntity[];\n\t\tconst noteIds = (await Promise.all(folderIds.map(id => Folder.noteIds(id, { includeConflicts: true, includeDeleted: true })))).flat();\n\t\tconst notes = await Note.loadItemsByIds(noteIds) as NoteEntity[];\n\t\tconst directlyPublishedNoteIds = new Set(remainingShares\n\t\t\t.filter(s => s.type === ShareType.Note && !!s.note_id)\n\t\t\t.map(s => s.note_id));\n\n\t\tfor (const folderItem of folders) {\n\t\t\tawait Folder.updateShareStatus({ ...folderItem, type_: ModelType.Folder }, false);\n\t\t}\n\n\t\tfor (const note of notes) {","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/laurent22/joplin/blob/dc4e0b464e43f63851261b0f72fb59d301fc99a7/packages/lib/services/share/ShareService.ts#L309-L345","documentation":"Thrown by ShareService.unpublishFolder() when Folder.load(folderId) returns null, meaning no folder with that ID exists in the local database. Share operations run entirely against the local Joplin database (not the server), so the folder must have been synced to this device before it can be unpublished. The error is a plain guard clause at the top of the method, before any share state or network call is touched.","triggerScenarios":"Calling unpublishFolder(folderId) with an ID that is not in the local folders table: a typo'd/truncated ID, an ID from a different profile or device that was never synced, a folder already deleted locally (e.g. in the trash or removed by a previous sync), or passing a note ID where a folder ID is expected.","commonSituations":"Scripts or plugins that capture a folder ID, delete/recreate the folder, then call unpublish with the stale ID; UI acting on a stale selection after the folder was deleted on another device and synced away; multi-profile setups where the ID belongs to another profile's database.","solutions":["Verify the folder exists locally first: const folder = await Folder.load(folderId) and bail or re-render if null.","Make sure sync has run to completion on this device so the folder row exists before invoking share operations.","Check the ID source: confirm you are passing the folder's id (not parent_id, not a note id, not a share id).","If the folder was deleted intentionally, treat 'No such folder' as success (nothing left to unpublish) instead of letting it bubble up."],"exampleFix":"// before\nawait shareService.unpublishFolder(folderId);\n\n// after\nconst folder = await Folder.load(folderId);\nif (!folder) return; // nothing to unpublish locally\nawait shareService.unpublishFolder(folderId);","handlingStrategy":"validation","validationCode":"import { Folder } from '@joplin/lib/models/Folder';\n\nconst folder = await Folder.load(folderId);\nif (!folder) {\n\t// Folder is not in the local database: resync, or treat as nothing-to-unpublish\n\treturn;\n}","typeGuard":"const isExistingFolder = (f: FolderEntity | null): f is FolderEntity => !!f;","tryCatchPattern":"try {\n\tawait shareService.unpublishFolder(folderId);\n} catch (error) {\n\tif (error instanceof Error && error.message.startsWith('No such folder:')) {\n\t\t// Local DB lacks the folder: run a sync and retry once, or accept as no-op\n\t} else {\n\t\tthrow error;\n\t}\n}","preventionTips":["Always resolve entities from the local database (Folder.load) before passing their IDs into share operations.","Ensure sync has completed on this device before exposing publish/unpublish actions.","Never reuse folder IDs captured in a previous session without re-validating them."],"tags":["joplin","sharing","folder","not-found","local-database"],"backgroundTag":"entity-not-found","analyzedSha":"dc4e0b464e43f63851261b0f72fb59d301fc99a7","analyzedAt":"2026-08-21T12:05:35.031Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}