laurent22/joplin · error · Error
Unsupported protocol
Error message
Unsupported protocol
What it means
Thrown when the link does not start with 'joplin://' or ':/' AND urlProtocol(link) returns a falsy value — i.e. the string has no recognizable scheme (no `scheme:` prefix). Joplin hands unknown-scheme URLs to the OS via shim.openUrl; with no scheme at all, there is nothing to open.
Source
Thrown at packages/app-mobile/commands/openItem.ts:64
const parsedResourceUrl = parseResourceUrl(link);
const parsedCallbackUrl = isCallbackUrl(link) ? parseCallbackUrl(link) : null;
if (parsedResourceUrl) {
const { itemId, hash } = parsedResourceUrl;
await openItemById(itemId, hash);
} else if (parsedCallbackUrl) {
const id = parsedCallbackUrl.params.id;
if (!id) {
throw new Error('Missing item ID');
}
await openItemById(id);
} else {
throw new Error('Unsupported link format.');
}
} else if (urlProtocol(link)) {
shim.openUrl(link);
} else {
throw new Error('Unsupported protocol');
}
} catch (error) {
const errorMessage = _('Unsupported link or message: %s.\nError: %s', link, error);
logger.error(errorMessage);
await shim.showErrorDialog(errorMessage);
}
},
};
};
View on GitHub (pinned to 2654b33620)
Solutions
- Prefix the link with a scheme (https://, mailto:, etc.) before invoking openItem.
- Sanitize/trim the link string and re-detect its protocol.
- Reject empty-protocol strings earlier in the input pipeline.
- Catch and inform the user the link has no usable protocol.
Example fix
// before
} else {
throw new Error('Unsupported protocol');
}
// after — explain what was expected
} else {
throw new Error(_('Unsupported protocol in link: %s', link));
} Defensive patterns
Strategy: validation
Validate before calling
const proto = urlProtocol(link);
if (!proto) {
// no scheme — refuse, or prepend a default like https:// if appropriate
return;
}
await CommandService.instance().execute('openItem', link); Type guard
function hasProtocol(link: string): boolean {
return !!urlProtocol(link);
} Try / catch
try {
await CommandService.instance().execute('openItem', link);
} catch (e) {
if (e.message === 'Unsupported protocol') {
// inform the user the link has no usable scheme
} else throw e;
} Prevention
- Ensure links carry a scheme (https://, mailto:, joplin://) before invoking openItem.
- Trim/sanitize pasted links so leading whitespace doesn't strip the scheme.
- Reject protocol-less strings early in the input pipeline.
When it happens
Trigger: link fails the joplin:///:/ check, then urlProtocol(link) is falsy (no protocol/scheme detected). The final else throws 'Unsupported protocol'.
Common situations: A bare string with no scheme (e.g. 'example.com' instead of 'https://example.com'); a relative path passed as a link; whitespace/control characters stripping the scheme; a malformed paste.
Related errors
- Unsupported link format.
- Item not found: ${itemId}
- Unsupported item type for links: ${item.type_}
- Link cannot be empty
- Missing item ID
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/9b04a4a9f9466646.
Report an issue: GitHub.