{"record":{"id":"80dc9bf661a37209","repo":"laurent22/joplin","slug":"unsupported-link-format","errorCode":null,"errorMessage":"Unsupported link format.","messagePattern":"Unsupported link format\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-mobile/commands/openItem.ts","lineNumber":59,"sourceCode":"\t\texecute: async (_context: CommandContext, link: string) => {\n\t\t\tif (!link) throw new Error('Link cannot be empty');\n\n\t\t\ttry {\n\t\t\t\tif (link.startsWith('joplin://') || link.startsWith(':/')) {\n\t\t\t\t\tconst parsedResourceUrl = parseResourceUrl(link);\n\t\t\t\t\tconst parsedCallbackUrl = isCallbackUrl(link) ? parseCallbackUrl(link) : null;\n\n\t\t\t\t\tif (parsedResourceUrl) {\n\t\t\t\t\t\tconst { itemId, hash } = parsedResourceUrl;\n\t\t\t\t\t\tawait openItemById(itemId, hash);\n\t\t\t\t\t} else if (parsedCallbackUrl) {\n\t\t\t\t\t\tconst id = parsedCallbackUrl.params.id;\n\t\t\t\t\t\tif (!id) {\n\t\t\t\t\t\t\tthrow new Error('Missing item ID');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait openItemById(id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error('Unsupported link format.');\n\t\t\t\t\t}\n\t\t\t\t} else if (urlProtocol(link)) {\n\t\t\t\t\tshim.openUrl(link);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error('Unsupported protocol');\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst errorMessage = _('Unsupported link or message: %s.\\nError: %s', link, error);\n\t\t\t\tlogger.error(errorMessage);\n\t\t\t\tawait shim.showErrorDialog(errorMessage);\n\t\t\t}\n\t\t},\n\t};\n};\n","sourceCodeStart":41,"sourceCodeEnd":74,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-mobile/commands/openItem.ts#L41-L74","documentation":"Thrown when a link starts with 'joplin://' or ':/' (so it enters the internal-link branch) but neither parseResourceUrl nor parseCallbackUrl can make sense of it. The link claims to be a Joplin internal link but matches no known internal-link grammar.","triggerScenarios":"link.startsWith('joplin://') or ':/' is true; parseResourceUrl(link) returns null; isCallbackUrl(link) is false (or parseCallbackUrl yields null). The else branch throws 'Unsupported link format.'.","commonSituations":"A typo'd or partially-typed internal link; a link using a joplin:// sub-scheme the parser doesn't recognize; a future link format not yet handled; the link was edited manually and broke its structure.","solutions":["Regenerate the internal link via Joplin's 'copy note link' / 'copy resource link'.","Compare the failing link against a known-good one to spot structural differences.","If introducing a new link grammar, add a parser branch before the else.","Catch the error and surface the link verbatim to the user for correction."],"exampleFix":"// before\n} else {\n  throw new Error('Unsupported link format.');\n}\n\n// after — show the link so the user can correct it\n} else {\n  throw new Error(_('Unsupported link format: %s', link));\n}","handlingStrategy":"validation","validationCode":"const isInternal = link.startsWith('joplin://') || link.startsWith(':/');\nconst resourceUrl = isInternal ? parseResourceUrl(link) : null;\nconst callbackUrl = isInternal && isCallbackUrl(link) ? parseCallbackUrl(link) : null;\nif (isInternal && !resourceUrl && !callbackUrl) {\n  // unsupported internal format — do not navigate\n  return;\n}","typeGuard":"function isRecognizedInternalLink(link: string): boolean {\n  if (!link.startsWith('joplin://') && !link.startsWith(':/')) return false;\n  return !!parseResourceUrl(link) || (isCallbackUrl(link) && !!parseCallbackUrl(link));\n}","tryCatchPattern":"try {\n  await CommandService.instance().execute('openItem', link);\n} catch (e) {\n  if (e.message === 'Unsupported link format.') {\n    // show the link verbatim and ask the user to correct it\n  } else throw e;\n}","preventionTips":["Generate internal links via Joplin's built-in copy-link actions.","Compare a failing link to a known-good one to spot structural breaks.","Add a parser branch before the else when introducing new link grammars."],"tags":["mobile","links","validation","url-parsing"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}