laurent22/joplin · error · Error
No such note: ${noteId}
Error message
No such note: ${noteId} What it means
Thrown by ShareService.unshareNote() when Note.load(noteId) returns null, i.e. the note does not exist in the local database. As with the folder guards, share services operate on the local SQLite/IndexedDB content, so the note must already be synced to this device. The check runs before loadSharesByItem() hits the network, so no API call is made when it fires.
Source
Thrown at packages/lib/services/share/ShareService.ts:358
for (const folderItem of folders) {
await Folder.updateShareStatus({ ...folderItem, type_: ModelType.Folder }, false);
}
for (const note of notes) {
await Note.updateShareStatus({ ...note, type_: ModelType.Note }, directlyPublishedNoteIds.has(note.id));
}
await Folder.updateAllShareIds(ResourceService.instance(), remainingShares);
// Clean local state first so next sync can recover if deletion stops midway
await this.deleteShare(share.id);
await this.refreshShares();
}
public async unshareNote(noteId: string) {
const note = await Note.load(noteId);
if (!note) throw new Error(`No such note: ${noteId}`);
const noteShares = (await this.loadSharesByItem(noteId))
.filter(s => s.type === ShareType.Note);
const promises: Promise<void>[] = [];
for (const share of noteShares) {
promises.push(this.deleteShare(share.id));
}
await Promise.all(promises);
await Note.save({
id: note.id,
parent_id: note.parent_id,
is_shared: 0,
updated_time: Date.now(),
}, {View on GitHub (pinned to dc4e0b464e)
Solutions
- Validate first: const note = await Note.load(noteId); skip or surface a friendly message if null.
- Re-run sync before unsharing so notes created/deleted elsewhere are reflected locally.
- Audit where the noteId comes from — if it originates from share.note_id, the share may outlive the note; handle that case explicitly.
- If the goal is a clean slate, delete the orphan share directly via deleteShare(share.id) instead of unshareNote().
Example fix
// before await shareService.unshareNote(noteId); // after const note = await Note.load(noteId); if (!note) return; // note gone locally; nothing to unshare await shareService.unshareNote(noteId);
Defensive patterns
Strategy: validation
Validate before calling
import { Note } from '@joplin/lib/models/Note';
const note = await Note.load(noteId);
if (!note) {
return; // note absent locally; nothing to unshare
} Type guard
const isExistingNote = (n: NoteEntity | null): n is NoteEntity => !!n;
Try / catch
try {
await shareService.unshareNote(noteId);
} catch (error) {
if (error instanceof Error && error.message.startsWith('No such note:')) {
// Note deleted locally; optionally delete orphan shares via deleteShare(share.id)
} else {
throw error;
}
} Prevention
- Validate note existence with Note.load before calling unshareNote.
- When iterating shares, handle share.note_id whose note no longer exists instead of passing it through blindly.
- Run sync before batch unshare operations so local note state matches the server.
When it happens
Trigger: Calling unshareNote() with a non-existent or malformed note ID; the note was deleted locally (or moved to trash and purged) before the call; the note exists only on another device/profile and was never synced here; a note ID from a share object (share.note_id) whose underlying note was removed.
Common situations: Plugins or scripts that read share.note_id from a stale share list after the source note was deleted; race between a delete action and an unshare action in the UI; test fixtures that build share records without the matching note rows.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- No such folder: ${folderId}
- No published share for folder: ${folderId}
- Cannot find "%s".
- Cannot find "%s".
- No share found for folder ${folderId}
AI-assisted analysis of laurent22/joplin@dc4e0b464e (2026-08-21).
Data as JSON: /api/errors/8baeb1543b5d5d0b.
Report an issue: GitHub.