{"record":{"id":"eed1ac7fe49bd6c9","repo":"laurent22/joplin","slug":"unable-to-scroll-to-hash-no-note-open","errorCode":null,"errorMessage":"Unable to scroll to hash -- no note open.","messagePattern":"Unable to scroll to hash -- no note open\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/app-mobile/commands/scrollToHash.ts","lineNumber":13,"sourceCode":"import { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';\nimport NavService from '@joplin/lib/services/NavService';\n\nexport const declaration: CommandDeclaration = {\n\tname: 'scrollToHash',\n};\n\nexport const runtime = (): CommandRuntime => {\n\treturn {\n\t\texecute: async (context: CommandContext, hash: string) => {\n\t\t\tconst selectedNoteIds = context.state.selectedNoteIds;\n\t\t\tif (selectedNoteIds.length === 0) {\n\t\t\t\tthrow new Error('Unable to scroll to hash -- no note open.');\n\t\t\t}\n\n\t\t\tawait NavService.go('Note', {\n\t\t\t\tnoteId: selectedNoteIds[0],\n\t\t\t\tnoteHash: hash,\n\t\t\t});\n\t\t},\n\t};\n};\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-mobile/commands/scrollToHash.ts#L1-L23","documentation":"Thrown by the scrollToHash command when context.state.selectedNoteIds is empty. Scrolling to an anchor/hash requires an open note; with nothing selected there is no note to scroll within.","triggerScenarios":"Executing scrollToHash when the user has no note open (selectedNoteIds.length === 0). The guard fires before NavService.go, preventing navigation to a Note route with no noteId.","commonSituations":"A deep link / notification carrying a hash fires scrollToHash before any note is opened; the user returned to the notebook list; a plugin triggers scroll-to-hash programmatically without first opening a note.","solutions":["Ensure a note is selected/open before triggering scrollToHash.","If arriving from a deep link, open the target note first, then scroll.","Gate the command behind an enabledCondition of `someNotesSelected`.","Catch and ignore (or open the note) instead of throwing when no note is selected."],"exampleFix":"// before\nif (selectedNoteIds.length === 0) {\n  throw new Error('Unable to scroll to hash -- no note open.');\n}\n\n// after — no-op with optional fallback navigation\nif (selectedNoteIds.length === 0) {\n  logger.warn('scrollToHash called with no open note; ignoring.');\n  return;\n}","handlingStrategy":"validation","validationCode":"if (context.state.selectedNoteIds.length === 0) {\n  // no open note — open one first, or skip\n  return;\n}\nawait CommandService.instance().execute('scrollToHash', hash);","typeGuard":"function hasOpenNote(selectedNoteIds: string[]): boolean {\n  return Array.isArray(selectedNoteIds) && selectedNoteIds.length > 0;\n}","tryCatchPattern":"try {\n  await CommandService.instance().execute('scrollToHash', hash);\n} catch (e) {\n  if (e.message.includes('no note open')) {\n    // open the target note first, then re-scroll\n  } else throw e;\n}","preventionTips":["Open a note before triggering scrollToHash (e.g. from deep links, open note then scroll).","Gate the command behind a 'someNotesSelected' enabled condition.","For deep-link entry points, sequence openNote before scrollToHash."],"tags":["mobile","navigation","validation","selection"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}