Repository navigation
fix: fall back to internal storage when external storage is unavailable - #2781
Merged
bajrangCoder merged 2 commits intoAug 22, 2026
Merged
Conversation
Contributor
Greptile SummaryThe PR preserves the application entry points and adds resilient startup behavior when external storage is unavailable.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the previously reported deletion issue is invalid at the current head because all three application entry-point files remain present and contain targeted modifications. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Device ready] --> B[Probe external storage]
B -->|Available| C[Use external data and cache]
B -->|Unavailable| D[Use internal data and cache]
C --> E[Ensure plugins directory]
E -->|Creation succeeds| F[Continue application bootstrap]
E -->|Creation fails| D
D --> G[Ensure internal plugins directory]
G --> F
Reviews (2): Last reviewed commit: "fix: fall back to internal storage when ..." | Re-trigger Greptile |
ulite-Amr
marked this pull request as draft
August 20, 2026 22:08
ulite-Amr
force-pushed
the
fix/startup-storage-fallback
branch
from
August 20, 2026 22:09
313fcca to
e6fd161
Compare
ulite-Amr
marked this pull request as ready for review
August 20, 2026 22:10
The app used to pick the external data directory unconditionally and then create the plugins directory without guarding against failures. On devices where the external filesystem cannot be created (e.g. Android/data dir is not creatable), the unhandled rejection aborted startup, leaving users stuck on the splash screen with a misleading "Update Android System WebView or Chrome" message. - Probe external storage with fs.stat() and fall back to internal storage - Wrap plugins directory creation in try/catch and fall back to internal - Request storage permissions only on SDK < 33, guarded by hasPermission - Guard editorManager.hasUnsavedFiles() access in exitAppMessage - Show an honest "storage is unavailable" startup message for storage errors
ulite-Amr
force-pushed
the
fix/startup-storage-fallback
branch
from
August 21, 2026 00:03
e6fd161 to
43f8595
Compare
RohitKushvaha01
approved these changes
Aug 21, 2026
bajrangCoder
approved these changes
Aug 21, 2026
RohitKushvaha01
added a commit
to RohitKushvaha01/Acode
that referenced
this pull request
Sep 8, 2026
* fix: fall back to internal storage when external storage is unavailable (Acode-Foundation#2781) * fix: fall back to internal storage when external storage is unavailable The app used to pick the external data directory unconditionally and then create the plugins directory without guarding against failures. On devices where the external filesystem cannot be created (e.g. Android/data dir is not creatable), the unhandled rejection aborted startup, leaving users stuck on the splash screen with a misleading "Update Android System WebView or Chrome" message. - Probe external storage with fs.stat() and fall back to internal storage - Wrap plugins directory creation in try/catch and fall back to internal - Request storage permissions only on SDK < 33, guarded by hasPermission - Guard editorManager.hasUnsavedFiles() access in exitAppMessage - Show an honest "storage is unavailable" startup message for storage errors * fix: detect storage errors via FileError instanceof instead of numeric code range * fix(theme): prevent freeze when switching to system theme (Acode-Foundation#2790) * fix(sftp): cancel stalled connections and prevent delayed errors (Acode-Foundation#2791) * fix(sftp): cancel stalled connections and prevent delayed errors * fix race cases * fix: admob issues (Acode-Foundation#2800) * fix: admob issues * fix: restore Android build commands --------- Co-authored-by: Ajit Kumar <dellevenjack@gmail> * fix(android): avoid splash surface crash on realme Android 13 (Acode-Foundation#2805) * fix(session): restore picker documents and skip intent files tab (Acode-Foundation#2809) * fix(session): restore picker documents and skip intent files tab * feat(file-browser): expose document picker(icon) from nested folders * fix * feat(console): isolate execution and improve mobile REPL UX (Acode-Foundation#2808) * feat(console): isolate execution and improve mobile REPL UX - run console JavaScript in a cancellable Web Worker - protect the app from infinite loops and recursion - preserve history with variable-height virtualization - restore the inline REPL layout - fix mobile keyboard resizing and viewport gaps - add clear and stop controls * fix(console): address execution context and bottom pinning * address the pinning regression * remove stop, run btn * feat(console): follow active Acode theme (Acode-Foundation#2814) * feat(console): follow active Acode theme * fix * fix * chore: update deps * Enhanced: Indonesian (id) language translations (Acode-Foundation#2798) * update deps * fix: preserve MIME type for plugin icons on plugin details page (Acode-Foundation#2818) * fix: preserve MIME type for plugin icons on plugin details page * fix * fix(console): run JavaScript files in isolated worker (Acode-Foundation#2819) * fix(console): run JavaScript files in isolated worker * fix * feat: plugin review (Acode-Foundation#2826) * feat: plugin commit Allow logged in user to review plugins from the app. * fix: api url --------- Co-authored-by: Ajit Kumar <dellevenjack@gmail> * Improve selection menu UX and plugin action overflow (Acode-Foundation#2813) * feat(editor): improve mobile selection menu overflow UX * fix(editor): prevent selection actions during overflow scrolling * fix(editor): validate pointer displacement on release * fix(search): include restored files in global search (Acode-Foundation#2830) * fix(search): include restored files in global search * fix * chore: v1.13.2 * refactor(file-browser): Convert directory cache to `Map` instance (Acode-Foundation#2831) Replace the plain object container used for cached directories with an ES6 `Map` to improve key management semantics. Update cached directory data structure (`src/pages/fileBrowser/fileBrowser.js`): - Re-initialize `cachedDir` variable as a `Map` - Replace object property lookups with `Map.prototype.has()` and `Map.prototype.get()` - Update cache writes to use `Map.prototype.set()` - Update directory deletion calls to use `Map.prototype.delete()` (AI generated commit message) * fix(editor): stabilize selection menu sizing and transitions (Acode-Foundation#2833) * fix(editor): keep fullscreen controls above bottom pane tabs (Acode-Foundation#2834) * chore(community-release-notifier): Change sed parsing - TG release notes (Acode-Foundation#2832) * chore(community-release-notifier): Change sed parsing - TG release notes This commit fixes Release notes not being sed escaped properly leading towards Telegram notifier failing for Stable Releases as they were auto-generated by git. * Disable markdown format in community release notifier Commented out the markdown format option in the Telegram notifier. * fix(editor): restore cursor state and prevent tab-switch flash (Acode-Foundation#2835) * fix(editor): restore cursor state and prevent tab-switch flash * fix * feat(lsp): improve actions, navigation, and position handling (Acode-Foundation#2837) - advertise code action resolve support - clamp LSP positions beyond document bounds - support LocationLink and multiple navigation results - add LSP operations to the selection menu - fix navigation scrolling after switching files - use shared position and location normalization helpers * fix(editor): highlight all visible search matches (Acode-Foundation#2838) * Translation: Update hu-hu.json (Acode-Foundation#2828) * Translation: Update hu-hu.json Fixing AI-translated strings * Translation: Update hu-hu.json Fix typos * chore(deps): bump actions/setup-java from 5 to 6 (Acode-Foundation#2821) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5 to 6. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](actions/setup-java@v5...v6) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: improved pluginContext (Acode-Foundation#2806) * feat: improved pluginContext * Update src/lib/pluginContext.js Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * format * fix: holes * format * . --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(webview): retain instance when destroy fails (Acode-Foundation#2836) * fix(webview): retain instance when destroy fails * test(webview): cover destroy failure lifecycle * fix(webview): serialize concurrent destruction * test(webview): cover concurrent destruction * fix(sftp): recover from failed profile migration (Acode-Foundation#2840) * fix(sftp): recover from failed profile migration * fix(sftp): migrate folder-state URL keys * fix * fix * chore: v1.13.3 * fix: typo * fix: prevent Cordova exec startup race (Acode-Foundation#2851) * fix(editor): improve selection contrast on active lines (Acode-Foundation#2852) * fix(editor): treat missing write capability as editable (Acode-Foundation#2853) * fix(editor): treat missing write capability as editable * fix * fix: race condition when moving to exact line/col (Acode-Foundation#2856) * fix: race condition when moving to exact line/col * fix(search): cancel obsolete result navigation * fix(search): preserve loader during concurrent file opens * Add GitHub Actions workflow for congratulating Community PRs (Acode-Foundation#2855) * Shortcut For Opening Welcome Tab (Acode-Foundation#2773) * Update keyBindings.js * Fix formatting of welcomeTab key binding * Added new shortcut to open welcome window * Shortcut For Opening Welcome Tab * Update keyBindings.js * Modify welcomeTab key binding description Updated the description for the welcomeTab key binding. * Fix changes * Rename welcomeTab to acode:showWelcome fix cmd description and rename the command name to "acode:showWelcome" so that it matches the existing command and adds the keybind to it instead of a possibly new command. --------- Co-authored-by: Emmanuel Lobo <76094069+UnschooledGamer@users.noreply.github.com> * chore: Add Lingala (ln) translation (Acode-Foundation#2775) * Update Lingala translation * Add Lingala translation * Complete Lingala translation strings * chore: update Lingala translations * chore: update more Lingala translations * Complete Lingala translations * Update Lingala translation * Translate remaining strings to Lingala * Fix French strings in Lingala translation * Fix French strings in Lingala translation * Improve Lingala translation --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Amr Ayman <48989143+ulite-Amr@users.noreply.github.com> Co-authored-by: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Co-authored-by: Ajit Kumar <dellevenjack@gmail> Co-authored-by: TM <anonymous.matrixtm26.dev@gmail.com> Co-authored-by: AuDevTist1C <114492072+AuDevTist1C@users.noreply.github.com> Co-authored-by: Emmanuel Lobo <76094069+UnschooledGamer@users.noreply.github.com> Co-authored-by: summoner <summoner001@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rohit Kushvaha <oldisg131@gmail.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: azamkassim <azam.kassim.work@gmail.com> Co-authored-by: Game-Dev-Shubham <shubhamyadav1247878@gmail.com> Co-authored-by: Degrace <kiminoudegrace64@gmail.com>
pull Bot
pushed a commit
to AmirulAndalib/Acode
that referenced
this pull request
Sep 8, 2026
* feat: added icons and api * Update src/plugins/system/android/com/foxdebug/system/System.java Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * feat: added frontend * feat: added frontend * fix: add missing entries * fix: icons, new pro icon, icons for free version * Merge upstream main and resolve app icon conflicts (#2) * fix: fall back to internal storage when external storage is unavailable (Acode-Foundation#2781) * fix: fall back to internal storage when external storage is unavailable The app used to pick the external data directory unconditionally and then create the plugins directory without guarding against failures. On devices where the external filesystem cannot be created (e.g. Android/data dir is not creatable), the unhandled rejection aborted startup, leaving users stuck on the splash screen with a misleading "Update Android System WebView or Chrome" message. - Probe external storage with fs.stat() and fall back to internal storage - Wrap plugins directory creation in try/catch and fall back to internal - Request storage permissions only on SDK < 33, guarded by hasPermission - Guard editorManager.hasUnsavedFiles() access in exitAppMessage - Show an honest "storage is unavailable" startup message for storage errors * fix: detect storage errors via FileError instanceof instead of numeric code range * fix(theme): prevent freeze when switching to system theme (Acode-Foundation#2790) * fix(sftp): cancel stalled connections and prevent delayed errors (Acode-Foundation#2791) * fix(sftp): cancel stalled connections and prevent delayed errors * fix race cases * fix: admob issues (Acode-Foundation#2800) * fix: admob issues * fix: restore Android build commands --------- Co-authored-by: Ajit Kumar <dellevenjack@gmail> * fix(android): avoid splash surface crash on realme Android 13 (Acode-Foundation#2805) * fix(session): restore picker documents and skip intent files tab (Acode-Foundation#2809) * fix(session): restore picker documents and skip intent files tab * feat(file-browser): expose document picker(icon) from nested folders * fix * feat(console): isolate execution and improve mobile REPL UX (Acode-Foundation#2808) * feat(console): isolate execution and improve mobile REPL UX - run console JavaScript in a cancellable Web Worker - protect the app from infinite loops and recursion - preserve history with variable-height virtualization - restore the inline REPL layout - fix mobile keyboard resizing and viewport gaps - add clear and stop controls * fix(console): address execution context and bottom pinning * address the pinning regression * remove stop, run btn * feat(console): follow active Acode theme (Acode-Foundation#2814) * feat(console): follow active Acode theme * fix * fix * chore: update deps * Enhanced: Indonesian (id) language translations (Acode-Foundation#2798) * update deps * fix: preserve MIME type for plugin icons on plugin details page (Acode-Foundation#2818) * fix: preserve MIME type for plugin icons on plugin details page * fix * fix(console): run JavaScript files in isolated worker (Acode-Foundation#2819) * fix(console): run JavaScript files in isolated worker * fix * feat: plugin review (Acode-Foundation#2826) * feat: plugin commit Allow logged in user to review plugins from the app. * fix: api url --------- Co-authored-by: Ajit Kumar <dellevenjack@gmail> * Improve selection menu UX and plugin action overflow (Acode-Foundation#2813) * feat(editor): improve mobile selection menu overflow UX * fix(editor): prevent selection actions during overflow scrolling * fix(editor): validate pointer displacement on release * fix(search): include restored files in global search (Acode-Foundation#2830) * fix(search): include restored files in global search * fix * chore: v1.13.2 * refactor(file-browser): Convert directory cache to `Map` instance (Acode-Foundation#2831) Replace the plain object container used for cached directories with an ES6 `Map` to improve key management semantics. Update cached directory data structure (`src/pages/fileBrowser/fileBrowser.js`): - Re-initialize `cachedDir` variable as a `Map` - Replace object property lookups with `Map.prototype.has()` and `Map.prototype.get()` - Update cache writes to use `Map.prototype.set()` - Update directory deletion calls to use `Map.prototype.delete()` (AI generated commit message) * fix(editor): stabilize selection menu sizing and transitions (Acode-Foundation#2833) * fix(editor): keep fullscreen controls above bottom pane tabs (Acode-Foundation#2834) * chore(community-release-notifier): Change sed parsing - TG release notes (Acode-Foundation#2832) * chore(community-release-notifier): Change sed parsing - TG release notes This commit fixes Release notes not being sed escaped properly leading towards Telegram notifier failing for Stable Releases as they were auto-generated by git. * Disable markdown format in community release notifier Commented out the markdown format option in the Telegram notifier. * fix(editor): restore cursor state and prevent tab-switch flash (Acode-Foundation#2835) * fix(editor): restore cursor state and prevent tab-switch flash * fix * feat(lsp): improve actions, navigation, and position handling (Acode-Foundation#2837) - advertise code action resolve support - clamp LSP positions beyond document bounds - support LocationLink and multiple navigation results - add LSP operations to the selection menu - fix navigation scrolling after switching files - use shared position and location normalization helpers * fix(editor): highlight all visible search matches (Acode-Foundation#2838) * Translation: Update hu-hu.json (Acode-Foundation#2828) * Translation: Update hu-hu.json Fixing AI-translated strings * Translation: Update hu-hu.json Fix typos * chore(deps): bump actions/setup-java from 5 to 6 (Acode-Foundation#2821) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5 to 6. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](actions/setup-java@v5...v6) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: improved pluginContext (Acode-Foundation#2806) * feat: improved pluginContext * Update src/lib/pluginContext.js Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * format * fix: holes * format * . --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(webview): retain instance when destroy fails (Acode-Foundation#2836) * fix(webview): retain instance when destroy fails * test(webview): cover destroy failure lifecycle * fix(webview): serialize concurrent destruction * test(webview): cover concurrent destruction * fix(sftp): recover from failed profile migration (Acode-Foundation#2840) * fix(sftp): recover from failed profile migration * fix(sftp): migrate folder-state URL keys * fix * fix * chore: v1.13.3 * fix: typo * fix: prevent Cordova exec startup race (Acode-Foundation#2851) * fix(editor): improve selection contrast on active lines (Acode-Foundation#2852) * fix(editor): treat missing write capability as editable (Acode-Foundation#2853) * fix(editor): treat missing write capability as editable * fix * fix: race condition when moving to exact line/col (Acode-Foundation#2856) * fix: race condition when moving to exact line/col * fix(search): cancel obsolete result navigation * fix(search): preserve loader during concurrent file opens * Add GitHub Actions workflow for congratulating Community PRs (Acode-Foundation#2855) * Shortcut For Opening Welcome Tab (Acode-Foundation#2773) * Update keyBindings.js * Fix formatting of welcomeTab key binding * Added new shortcut to open welcome window * Shortcut For Opening Welcome Tab * Update keyBindings.js * Modify welcomeTab key binding description Updated the description for the welcomeTab key binding. * Fix changes * Rename welcomeTab to acode:showWelcome fix cmd description and rename the command name to "acode:showWelcome" so that it matches the existing command and adds the keybind to it instead of a possibly new command. --------- Co-authored-by: Emmanuel Lobo <76094069+UnschooledGamer@users.noreply.github.com> * chore: Add Lingala (ln) translation (Acode-Foundation#2775) * Update Lingala translation * Add Lingala translation * Complete Lingala translation strings * chore: update Lingala translations * chore: update more Lingala translations * Complete Lingala translations * Update Lingala translation * Translate remaining strings to Lingala * Fix French strings in Lingala translation * Fix French strings in Lingala translation * Improve Lingala translation --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Amr Ayman <48989143+ulite-Amr@users.noreply.github.com> Co-authored-by: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Co-authored-by: Ajit Kumar <dellevenjack@gmail> Co-authored-by: TM <anonymous.matrixtm26.dev@gmail.com> Co-authored-by: AuDevTist1C <114492072+AuDevTist1C@users.noreply.github.com> Co-authored-by: Emmanuel Lobo <76094069+UnschooledGamer@users.noreply.github.com> Co-authored-by: summoner <summoner001@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rohit Kushvaha <oldisg131@gmail.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: azamkassim <azam.kassim.work@gmail.com> Co-authored-by: Game-Dev-Shubham <shubhamyadav1247878@gmail.com> Co-authored-by: Degrace <kiminoudegrace64@gmail.com> * fix: lang * format --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Ajit Kumar <dellevenjack@gmail> Co-authored-by: Ajit Kumar <dellevenjack@gmail.com> Co-authored-by: Amr Ayman <48989143+ulite-Amr@users.noreply.github.com> Co-authored-by: Raunak Raj <71929976+bajrangCoder@users.noreply.github.com> Co-authored-by: TM <anonymous.matrixtm26.dev@gmail.com> Co-authored-by: AuDevTist1C <114492072+AuDevTist1C@users.noreply.github.com> Co-authored-by: Emmanuel Lobo <76094069+UnschooledGamer@users.noreply.github.com> Co-authored-by: summoner <summoner001@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: azamkassim <azam.kassim.work@gmail.com> Co-authored-by: Game-Dev-Shubham <shubhamyadav1247878@gmail.com> Co-authored-by: Degrace <kiminoudegrace64@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes the app failing to start on devices where the external storage directory cannot be created. On such devices users were stuck on the splash screen with a misleading "Acode failed to start. Update Android System WebView or Chrome." message — the WebView was fine, the problem was storage.
Reported by
Root cause
src/main.jsunconditionally picked the external data directory:window.DATA_STORAGE = externalDataDirectory || dataDirectory;fileplugin only registersfiles-externalif the external root directory can be created (newRoot.mkdirs()fails on affected devices), so the chosen URL points at a non-existent filesystem.if (!(await fsOperation(PLUGIN_DIR).exists())) await fsOperation(DATA_STORAGE).createDirectory("plugins");onDeviceReady()beforeloadApp(), leavingeditorManagernull and the splash screen forever — with the error handler blaming WebView/Chrome.Logcat evidence on an affected device:
Changes
src/main.jsresolveStorageDir()— probes the preferred directory withfs.stat()and falls back to internal storage when unavailableDATA_STORAGE/CACHE_STORAGE/PLUGIN_DIR/KEYBINDING_FILEto internal storage and retrieshasPermissionreturns false (ensurePermission()helper), preventing background-activity-launch blockssrc/lib/acode.js—editorManager?.hasUnsavedFiles?.() ?? 0inexitAppMessage(the error above was a downstream symptom of the aborted startup)www/index.html— startup error/rejection handlers now detect storage errors (FileError/NotFoundError/SecurityError/DOMException codes 1-12) and show an honest "Acode failed to start: storage is unavailable" message instead of blaming WebView/ChromeTested
The same patch was verified on an affected device: app now falls back to internal storage and starts normally, and storage errors produce an accurate message. CI (biome, typos, vitest) runs on this PR.
Fixes the class of startup failures reported as "Update Android System WebView or Chrome" that actually originate from unavailable external storage.