laurent22/joplin · error · Error

No share found for folder ${folder.id}

Error message

No share found for folder ${folder.id}

What it means

Thrown inside `commandShareRemove` after `ShareService.instance().refreshShares()` has been awaited, when the folder still has no share object in redux state. Because the refresh was just performed, this indicates the folder genuinely is not shared from the current account (rather than stale state). The folder.id is included for traceability.

Source

Thrown at packages/app-cli/app/command-share.ts:96

				can_read: 1,
				can_write: args.options['read-only'] ? 0 : 1,
			};
			logger.debug('Sharing folder', folder.id, 'with', email, 'permissions=', permissions);

			await ShareService.instance().addShareRecipient(share.id, share.master_key_id, email, permissions);

			await ShareService.instance().refreshShares();
			await ShareService.instance().refreshShareUsers(share.id);

			await reg.waitForSyncFinishedThenSync();
		};

		const commandShareRemove = async (folder: FolderEntity, email: string) => {
			await ShareService.instance().refreshShares();

			const share = getShareFromFolderId(folder.id);
			if (!share) {
				throw new Error(`No share found for folder ${folder.id}`);
			}

			await ShareService.instance().refreshShareUsers(share.id);

			const shareUsers = getShareUsers(folder.id);
			if (!shareUsers) {
				throw new Error(`No share found for folder ${folder.id}`);
			}

			const targetUser = shareUsers.find(user => user.user?.email === email);
			if (!targetUser) {
				throw new Error(`No recipient found with email ${email}`);
			}

			await ShareService.instance().deleteShareRecipient(targetUser.id);
			this.stdout(_('Removed %s from share.', targetUser.user.email));
		};

View on GitHub (pinned to 2654b33620)

Solutions

  1. Verify current shares with `share list <notebook>`; if none, the recipient was already removed — nothing to do.
  2. If you intended to unshare entirely, use `share delete <notebook>` instead of `share remove`.
  3. Confirm you are logged into the same account that owns the share.
  4. Sync and retry in case of a transient server-side inconsistency.

Example fix

// before
const share = getShareFromFolderId(folder.id);
if (!share) throw new Error(`No share found for folder ${folder.id}`);

// after - guide the user to the right subcommand
const share = getShareFromFolderId(folder.id);
if (!share) throw new Error(`Folder "${folder.title}" is not currently shared. Use \`share delete\` to unshare completely.`);
Defensive patterns

Strategy: validation

Validate before calling

await ShareService.instance().refreshShares();
const share = getShareFromFolderId(folder.id);
if (!share) {
	throw new Error(`Cannot remove a recipient: folder "${folder.title}" is not shared.`);
}

Type guard

null

Try / catch

try {
	await commandShareRemove(folder, email);
} catch (e) {
	if (/No share found/.test(e.message)) { /* tell user the folder is not shared */ }
	else throw e;
}

Prevention

When it happens

Trigger: Running `share remove <notebook> <email>` on a folder that was never shared via `share add`, or whose share was already deleted on the server and the deletion has now propagated. The refresh-then-check sequence makes this a authoritative negative result.

Common situations: Calling `remove` instead of `delete` on a folder you own and have already unshared; the recipient was already removed by another admin; share was created on a different Joplin Cloud account.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/51e3739aa3d1dd91. Report an issue: GitHub.