{"record":{"id":"186b6f8409748929","repo":"stablyai/orca","slug":"selected-file-is-not-a-markdown-document","errorCode":null,"errorMessage":"Selected file is not a markdown document.","messagePattern":"Selected file is not a markdown document\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/main/ipc/app.ts","lineNumber":57,"sourceCode":"async function pickFloatingMarkdownDocument(\n  event: IpcMainInvokeEvent\n): Promise<MarkdownDocument | null> {\n  const cwd = await ensureDefaultFloatingWorkspacePath()\n  const options = {\n    defaultPath: cwd,\n    properties: ['openFile'],\n    filters: [{ name: 'Markdown', extensions: ['md', 'mdx', 'markdown'] }]\n  } satisfies Electron.OpenDialogOptions\n  const parentWindow = BrowserWindow.fromWebContents(event.sender)\n  const result = parentWindow\n    ? await dialog.showOpenDialog(parentWindow, options)\n    : await dialog.showOpenDialog(options)\n  if (result.canceled || result.filePaths.length === 0) {\n    return null\n  }\n  const filePath = result.filePaths[0]\n  if (!isMarkdownDocumentName(filePath)) {\n    throw new Error('Selected file is not a markdown document.')\n  }\n  authorizeExternalPath(filePath)\n  return markdownDocumentFromFilePath(cwd, filePath, { outsideRootRelativePath: 'basename' })\n}\n\nasync function pickFloatingWorkspaceDirectory(\n  event: IpcMainInvokeEvent,\n  store: Store\n): Promise<string | null> {\n  const parentWindow = BrowserWindow.fromWebContents(event.sender)\n  const options = {\n    // Why: this picker only grants access to an existing directory; creation belongs to explicit file actions.\n    properties: ['openDirectory']\n  } satisfies Electron.OpenDialogOptions\n  const result = parentWindow\n    ? await dialog.showOpenDialog(parentWindow, options)\n    : await dialog.showOpenDialog(options)\n  if (result.canceled || result.filePaths.length === 0) {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/app.ts#L39-L75","documentation":"Thrown by the markdown-file-open IPC handler after the OS open dialog returns a path that fails isMarkdownDocumentName. Although the dialog filters by extensions ['md','mdx','markdown'], some platforms/dialog modes allow bypassing the filter (e.g. entering a full path, all-files mode, or programmatic invocation), so the handler re-validates the extension before authorizing access.","triggerScenarios":"User selects or types a path whose extension isn't .md/.mdx/.markdown despite the filter; the dialog is invoked in a mode that ignores filters; a renderer passes a filePath directly that wasn't filtered. Also possible on platforms where the filter is advisory.","commonSituations":"User selects 'All Files' and picks a .txt or .docx; path typed manually with wrong extension; cross-platform dialog behavior differences; programmatic call bypassing the dialog.","solutions":["Pick a file with a .md, .mdx, or .markdown extension.","If the document is in another format, convert/rename it to .md first.","Ensure the dialog is opened with the Markdown filter active and the user doesn't switch to All Files."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const MARKDOWN_EXT = /\\.(md|mdx|markdown)$/i\nfunction isMarkdownDocumentName(filePath: string): boolean {\n  return MARKDOWN_EXT.test(filePath)\n}","typeGuard":"function isMarkdownDocumentName(filePath: unknown): filePath is string {\n  return typeof filePath === 'string' && /\\.(md|mdx|markdown)$/i.test(filePath)\n}","tryCatchPattern":null,"preventionTips":["Guide users to keep the Markdown filter active in the dialog.","Re-validate the extension server-side even when a filter is set — filters are advisory on some platforms.","Surface a clear message asking the user to pick a .md/.mdx/.markdown file."],"tags":["ipc","markdown","filesystem","validation","dialog"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}