{"record":{"id":"158a80f68ea09baf","repo":"laurent22/joplin","slug":"missing-read-write-access-it-might-be-necessary-t","errorCode":null,"errorMessage":"Missing read-write access. It might be necessary to share the folder with the application again.","messagePattern":"Missing read-write access\\. It might be necessary to share the folder with the application again\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-mobile/utils/fs-driver/fs-driver-rn.web.worker.ts","lineNumber":203,"sourceCode":"\t\t}\n\n\t\tconst saved = await this.accessHandleDatabase_.queryExternalHandle(path);\n\t\tif (!saved) {\n\t\t\tlogger.debug('External lookup failed for', path);\n\t\t\treturn null;\n\t\t}\n\t\tconst [handle, mode] = saved;\n\n\t\t// At present, not all browsers support .queryPermission and .requestPermission on\n\t\t// saved file handles.\n\t\tif (!('queryPermission' in handle)) {\n\t\t\tlogger.warn('Browser does not support .queryPermission. Loading path: ', path);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst permission = { mode };\n\t\tif (await handle.queryPermission(permission) !== 'granted' && await handle.requestPermission(permission) !== 'granted') {\n\t\t\tthrow new Error('Missing read-write access. It might be necessary to share the folder with the application again.');\n\t\t}\n\n\t\tthis.externalHandles_.set(path, handle);\n\t\treturn handle;\n\t}\n\n\tprivate async pathToDirectoryHandle_(path: string, create = false): Promise<FileSystemDirectoryHandle|null> {\n\t\tawait this.initPromise_;\n\t\tpath = resolve('/', path);\n\n\t\tif (path === '/') {\n\t\t\treturn this.fsRoot_;\n\t\t} else if (`${path}/`.startsWith(externalDirectoryPrefix)) {\n\t\t\tif (path === externalDirectoryPrefix || `${path}/` === externalDirectoryPrefix) {\n\t\t\t\t// /external/ is virtual, it doesn't exist.\n\t\t\t\treturn null;\n\t\t\t}\n","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/app-mobile/utils/fs-driver/fs-driver-rn.web.worker.ts#L185-L221","documentation":"Thrown by the web-worker RN fs-driver when a previously-saved directory handle no longer has the requested read-write permission and `requestPermission` also fails to grant it. Used to guard against silently writing to a folder the user has revoked access to. The fix the message suggests is re-sharing the folder.","triggerScenarios":"The user previously granted a folder, then revoked permission via browser/site settings; the saved `FileSystemDirectoryHandle` is still cached but its permission state is 'denied' or 'prompt' and the prompt was dismissed/denied.","commonSituations":"Browser auto-expiry of granted permissions; user cleared site data; incognito session losing handle persistence; the browser does not support `queryPermission` (logged as a warning, not thrown).","solutions":["Re-share the folder with the app via the directory picker (re-trigger `mountExternalDirectory`).","Catch the error and surface a UI prompt asking the user to re-grant access.","Before heavy operations, pre-check `handle.queryPermission({ mode: 'readwrite' })` and request early when state is 'prompt'.","Detect unsupported browsers via the `'queryPermission' in handle` check and warn the user."],"exampleFix":"// before\nawait driver.mountExternalDirectory(handle, id, 'readwrite');\n\n// after\ntry {\n  await driver.mountExternalDirectory(handle, id, 'readwrite');\n} catch (error) {\n  await showReShareFolderPrompt();\n}","handlingStrategy":"try-catch","validationCode":"const granted =\n  !('queryPermission' in handle) ||\n  await handle.queryPermission({ mode }) === 'granted' ||\n  await handle.requestPermission({ mode }) === 'granted';\nif (!granted) {\n  await showReShareFolderPrompt();\n}","typeGuard":"const hasPermissionApi = (h: unknown): h is FileSystemDirectoryHandle &\n  { queryPermission(o: { mode: string }): Promise<string>;\n    requestPermission(o: { mode: string }): Promise<string> } =>\n  !!h && typeof (h as any).queryPermission === 'function';","tryCatchPattern":"try {\n  await driver.pathToDirectoryHandle_(path);\n} catch (error) {\n  if (/Missing read-write access/i.test(error.message)) {\n    await showReShareFolderPrompt();\n    return;\n  }\n  throw error;\n}","preventionTips":["Pre-check queryPermission and request early when state is 'prompt'.","Re-prompt the user to re-share the folder on revocation.","Detect unsupported browsers (no queryPermission) and warn the user."],"tags":["filesystem","web","permissions","file-system-access","mobile"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}