{"record":{"id":"c3bc0475989911ec","repo":"lyswhut/lx-music-desktop","slug":"id-or-url-missing","errorCode":null,"errorMessage":"id or url missing","messagePattern":"id or url missing","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/core/useApp/useDeeplink/useSonglistAction.js","lineNumber":54,"sourceCode":"      id: null,\n      url: null,\n    }\n    if (data) {\n      songlistInfo = data\n    } else {\n      songlistInfo.source = paths[0]\n      songlistInfo.url = paths[1]\n    }\n\n    sourceVerify(songlistInfo.source)\n\n    songlistInfo = dataVerify([\n      { key: 'source', types: ['string'] },\n      { key: 'id', types: ['string', 'number'], max: 64 },\n      { key: 'url', types: ['string'], max: 500 },\n    ], songlistInfo)\n\n    if (!songlistInfo.id && !songlistInfo.url) throw new Error('id or url missing')\n    if (isShowPlayerDetail.value) setShowPlayerDetail(false)\n    handleOpenSonglist(songlistInfo)\n    focusWindow()\n  }\n}\nconst usePlaySonglistDetail = () => {\n  const playSongListDetail = usePlaySonglist()\n\n  return async({ paths, data }) => {\n    let songlistInfo = {\n      source: null,\n      id: null,\n      url: null,\n      index: null,\n    }\n    if (data) {\n      songlistInfo = data\n    } else {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/lyswhut/lx-music-desktop/blob/9c364b482e5621a1d38b50e8610d2fb974457e6e/src/renderer/core/useApp/useDeeplink/useSonglistAction.js#L36-L72","documentation":"useOpenSonglist in useSonglistAction.js:54 requires at least one identifier — an `id` or a `url` — to open a songlist detail route. After dataVerify produces a sanitized songlistInfo, if both id and url are falsy the handler throws 'id or url missing' rather than routing to an empty detail view.","triggerScenarios":"An 'open songlist' deep link supplies a valid source (passes sourceVerify) but neither an id nor a url — e.g. paths has only one segment (the source) and no second element, or the data object omits both keys.","commonSituations":"A share link template that forgot the list id; path parsing placed the id in the wrong slot; the sender's data payload was constructed without an id/url.","solutions":["Ensure the deep link includes either an id or a url alongside the source (paths[1] or data.id/data.url).","Validate paths.length >= 2 (or presence of data.id/data.url) before invoking handleOpenSonglist.","Catch the throw at the deeplink router and show a user-facing 'invalid songlist link' dialog.","If url-only links are intended, confirm the url field is being populated from paths[1]."],"exampleFix":"// before\n    if (!songlistInfo.id && !songlistInfo.url) throw new Error('id or url missing')\n\n// after - guard before calling, and a clearer message\n    if (!songlistInfo.id && !songlistInfo.url) {\n      throw new Error('id or url missing: provide data.id or data.url (or paths[1]) for source=' + songlistInfo.source)\n    }","handlingStrategy":"validation","validationCode":"const hasSonglistId = (info) =>\n  (info?.id != null && info.id !== '') || (info?.url != null && info.url !== '')\nif (!hasSonglistId(info)) {\n  showErrorDialog('Songlist link is missing an id or url')\n  return\n}","typeGuard":"const hasSonglistId = (info) =>\n  Boolean(info) && ((typeof info.id === 'string' || typeof info.id === 'number') || typeof info.url === 'string')","tryCatchPattern":"try {\n  handleOpenSonglist(info)\n} catch (e) {\n  errorDialog(e.message)\n}","preventionTips":["Ensure paths[1] (id/url) is populated before the open-songlist handler runs.","Validate identifier presence at the router, before reaching dataVerify.","Treat a source-only link as user-facing invalid rather than a thrown error."],"tags":["deeplink","validation","songlist"],"backgroundTag":null,"analyzedSha":"9c364b482e5621a1d38b50e8610d2fb974457e6e","analyzedAt":"2026-08-12T15:14:48.244Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}