Skip to content

[Due for payment 2026-08-17] [$75 Due for payment 2026-06-30] [Onyx] Investigate null storage error #87867

Closed

Description

@fabioh8010

Coming from #87844.

Summary

Let's investigate the following Onyx storage error: null, which accounts for 90,661 (2.7%) of the 3,364,645 analysed errors during a time span of 1 month. Full details about the investigation and methodology are in #87844.

Platforms Top Methods
Desktop Safari (40K), Desktop Chrome (26K), iOS Safari (15K), Desktop Edge (7K) setWithRetry (80K), multiSetWithRetry (9K)
Retries Exhausted Evictions No Eviction Quota Checks >= 95% Full Mean % Full Quota Check Failed
13,089 23 0 254 0 0.1% 0
  • The error object was null — no useful error message was provided by the storage backend
  • Cross-browser, slightly Safari-leaning — may be a Safari-specific issue where the error object is not properly populated

Action Items

  • Investigate with Sentry, VictoriaLogs and Fullstory to understand user scenarios — what operations trigger a null error?
  • Improve error capturing in OnyxUtils.retryOperation — when the error message is null, try to capture additional context (e.g., stringify the full error object, capture error type/code/name even when message is null) to help diagnose these cases

Issue OwnerCurrent Issue Owner: @mallenexpensify

Activity

  1. sosek108 commented on Jun 1, 2026

    @sosek108
    Contributor

    I'll be investigating this issue

  2. sosek108 commented on Jun 3, 2026

    @sosek108
    Contributor

    Investigation summary

    Root cause

    The log **[Onyx]** Failed to save to storage. Error: null originates on web only, in the IDBKeyValProvider path. It is most likely related to aborted database transactions and how idb-keyval handles them

    idb-keyval handles database transactions via promisifyRequest and handles request.onabort by rejecting the request with request.error. When browser aborts any transaction, it does not treat this as error so reject is called with null. Line: https://github.com/jakearchibald/idb-keyval/blob/0c06d2659532745aef83fe01f7e8b4fb76b708d1/src/index.ts#L8

    Disclaimer: the error is null so we cannot exclude that there are multiple causes for this. Described solution can be confirmed with transaction.abort() call in code

    This may be related to QuotaExceededError. Look into example logs:

    {"_msg":"[App] 2026-04-21T12:49:45.113Z - [info] [Onyx] Failed to save to storage. Error: UnknownError: Connection is closing because of: IO error: ...\\https_new.expensify.com_0.indexeddb.leveldb/000030.log: FILE_ERROR_NO_SPACE (ChromeMethodBFE: 3::WritableFileAppend:│
    {"_msg":"[App] 2026-04-21T12:49:45.218Z - [info] [Onyx] Failed to save to storage. Error: null. onyxMethod: setWithRetry. retryAttempt: 2/5 ~~ parameters: \u0027\u0027 userAgent: \u0027Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chr│
    {"_msg":"[App] 2026-04-21T12:51:00.913Z - [info] [Onyx] Failed to save to storage. Error: AbortError: The transaction was aborted, so the request cannot be fulfilled.. onyxMethod: mergeCollectionWithPatches. retryAttempt: 2/5 ~~ parameters: \u0027\u0027 userAgent: \u00┤
    

    For set we have null and for merge there is AbortError which confirms the case.

  3. sosek108 commented on Jun 3, 2026

    @sosek108
    Contributor

    Prepared draft PR Expensify/react-native-onyx#796. It unifies the way set and merge works and we want AbortError to be surfaced in case of transaciton.abort().

    Previously IDB.set() was used and it surfaced transaction.error instead of request.error which was null.

    Additionally I provided tests that confirms if transaction abort is surfaced via AbortError

  4. sosek108 commented on Jun 3, 2026

    @sosek108
    Contributor

    PR is ready for review

  5. sosek108 commented on Jun 3, 2026

    @sosek108
    Contributor
  6. sosek108 commented on Jun 3, 2026

    @sosek108
    Contributor

    OOO notice 🌴: tomorrow there is Bank Holiday in Poland and I have vacation on Friday so I'll be OOO until Monday 8th.

  7. sosek108 commented on Jun 9, 2026

    @sosek108
    Contributor

    Another OOO notice 🌴: tommorow I start my planned vacation and I'm back on Monday.

  8. 15 remaining items

  9. changed the title [-][Due for payment 2026-06-30] [Onyx] Investigate `null` storage error[/-] [+][$75 Due for payment 2026-06-30] [Onyx] Investigate `null` storage error[/+] on Jul 28, 2026
  10. fabioh8010 commented on Aug 17, 2026

    @fabioh8010
    ContributorAuthor

    Hi @Julesssss are we done here?

  11. brunovjk commented on Aug 17, 2026

    @brunovjk
    Contributor

    Reopening to handle review payment for @brunovjk.

    I believe we just need to handle the payment, @fabioh8010. Thank you.

  12. changed the title [-][$75 Due for payment 2026-06-30] [Onyx] Investigate `null` storage error[/-] [+][Due for payment 2026-08-17] [$75 Due for payment 2026-06-30] [Onyx] Investigate `null` storage error[/+] on Aug 17, 2026
  13. melvin-bot commented on Aug 17, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  14. melvin-bot commented on Aug 17, 2026

    @melvin-bot

    Payment Summary

    Resolving PRs:

    BugZero Checklist (@mallenexpensify)

    • I have confirmed assignees, roles, and Upwork contracts look correct
    • I have paid out Upwork contracts / manual NewDot requests
  15. mallenexpensify commented on Aug 18, 2026

    @mallenexpensify
    Contributor

    Payment Summary

    Contributor+: @brunovjk due $75 via NewDot

    Made $75 cuz that's what's in title, comment/reopen if ya disagree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionWeeklyKSv2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions