laurent22/joplin · error · Error
Missing item ID
Error message
Missing item ID
What it means
Thrown when a parsed Joplin callback URL (isCallbackUrl was true and parseCallbackUrl succeeded) has no `id` parameter in its params. The callback-URL branch needs an id to locate the target item; without it, openItemById cannot be called.
Source
Thrown at packages/app-mobile/commands/openItem.ts:55
};
export const runtime = (): CommandRuntime => {
return {
execute: async (_context: CommandContext, link: string) => {
if (!link) throw new Error('Link cannot be empty');
try {
if (link.startsWith('joplin://') || link.startsWith(':/')) {
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
- Inspect the full callback URL and confirm it includes an `id` query parameter.
- Regenerate the link from Joplin's built-in 'copy link' to ensure correct params.
- If building callback URLs, always include `id`.
- Catch the error and prompt the user for a valid link.
Example fix
// before
const id = parsedCallbackUrl.params.id;
if (!id) throw new Error('Missing item ID');
// after — include the offending URL for diagnosis
const id = parsedCallbackUrl.params.id;
if (!id) throw new Error(`Missing item ID in callback URL: ${link}`); Defensive patterns
Strategy: validation
Validate before calling
const parsed = isCallbackUrl(link) ? parseCallbackUrl(link) : null;
if (parsed && !parsed.params.id) {
// reject the callback URL before navigation
throw new Error(`Callback URL missing id: ${link}`);
} Type guard
function callbackUrlHasId(parsed: { params: Record<string, string> } | null): boolean {
return parsed != null && typeof parsed.params.id === 'string' && parsed.params.id.length > 0;
} Try / catch
try {
await CommandService.instance().execute('openItem', link);
} catch (e) {
if (e.message === 'Missing item ID') {
// prompt user for a valid callback URL
} else throw e;
} Prevention
- When building callback URLs, always include the `id` parameter.
- Use Joplin's own 'copy link' to generate well-formed callback URLs.
- Validate parsed.params.id before attempting navigation.
When it happens
Trigger: A link matching the callback-URL shape (e.g. joplin://x-callback-url/open) parses successfully but its query params lack `id`. The `if (!id)` guard fires.
Common situations: A malformed or truncated callback URL; a callback URL built by a third-party tool that omits the required id param; copy-paste truncation dropping the id query segment.
Related errors
- Item not found: ${itemId}
- Unsupported item type for links: ${item.type_}
- Link cannot be empty
- Unsupported link format.
- Unsupported protocol
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/efce600721488abf.
Report an issue: GitHub.