{"record":{"id":"2f0b8df073555a37","repo":"AvaloniaUI/Avalonia","slug":"permissions-denied","errorCode":null,"errorMessage":"Permissions denied","messagePattern":"Permissions denied","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Browser/Avalonia.Browser/webapp/modules/storage/storageItem.ts","lineNumber":181,"sourceCode":"        return await ((item.handle as any).move(destination /*, newName */) as Promise<any>);\n    }\n\n    private async verifyPermissions(mode: \"read\" | \"readwrite\"): Promise<void | never> {\n        if (!this.handle) {\n            return;\n        }\n\n        // If we are using polyfill, let it decide permissions by itself, we can't request anything in this case.\n        if (!Caniuse.hasNativeFilePicker()) {\n            return;\n        }\n\n        if (await this.handle.queryPermission({ mode }) === \"granted\") {\n            return;\n        }\n\n        if (await this.handle.requestPermission({ mode }) === \"denied\") {\n            throw new Error(\"Permissions denied\");\n        }\n    }\n\n    public static async saveBookmark(item: StorageItem): Promise<string | null> {\n        // If file was previously bookmarked, just return old one.\n        if (item.bookmarkId) {\n            return item.bookmarkId;\n        }\n\n        // Bookmarks are not supported with polyfill.\n        if (!item.handle || !Caniuse.hasNativeFilePicker()) {\n            return null;\n        }\n\n        const connection = await avaloniaDb.connect();\n        try {\n            const key = await connection.put(fileBookmarksStore, item.handle, item.generateBookmarkId());\n            return key as string;","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Browser/Avalonia.Browser/webapp/modules/storage/storageItem.ts#L163-L199","documentation":"Thrown by StorageItem.verifyPermissions when handle.requestPermission({mode}) resolves to 'denied'. After queryPermission is not 'granted', the code requests permission; if the user denies the browser permission prompt (or a prior denial is sticky), this error aborts the operation.","triggerScenarios":"Any storage operation (openRead/openWrite/createFile/createFolder/moveAsync) that calls verifyPermissions('read'|'readwrite') and the user dismisses or denies the permission prompt, or requestPermission returns 'denied' because the site lacks persistence/engagement.","commonSituations":"User clicks 'Block' on the file-system permission prompt; the origin is in a denied state from a previous session; calling readwrite without the handle being granted; ephemeral/private browsing where prompts auto-deny.","solutions":["Catch the error and surface a clear UI asking the user to grant permission, then retry.","Check handle.queryPermission first and only call the operation when it is 'granted', requesting permission via a user gesture.","Ensure the permission request originates from a user gesture (click), as browsers may auto-deny non-gesture requests.","Fall back to a non-persistent path (download/upload) if permission is persistently denied."],"exampleFix":"// before\nconst file = await StorageItem.openRead(item); // user denied -> throws\n\n// after\nconst status = await item.handle?.queryPermission({ mode: 'read' });\nif (status !== 'granted') { showPermissionPrompt(); return; }\ntry { const file = await StorageItem.openRead(item); }\ncatch (e) { if (e.message === 'Permissions denied') showRetryUI(); else throw e; }","handlingStrategy":"try-catch","validationCode":"async function ensurePermission(handle: FileSystemHandle, mode: 'read' | 'readwrite'): Promise<boolean> {\n  if (await handle.queryPermission({ mode }) === 'granted') return true;\n  return await handle.requestPermission({ mode }) === 'granted';\n}","typeGuard":"function hasQueryablePermission(handle: any): boolean {\n  return !!handle && typeof handle.queryPermission === 'function';\n}","tryCatchPattern":"try { return await StorageItem.openRead(item); }\ncatch (e) {\n  if (e instanceof Error && e.message === 'Permissions denied') { showPermissionRetryUI(); return null; }\n  throw e;\n}","preventionTips":["Request permission from a user gesture (click).","Check queryPermission before operating; only request when not granted.","Offer a non-persistent fallback (download/upload) if denied."],"tags":["browser","storage","file-system-access","permissions","typescript"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}