Skip to content

[$1500] Expose Onyx.get #101910

Open
Open

Description

@chuckdries

Coming from #expert-contributors

Problem

Some components subscribe to Onyx values purely so they can pass them to event handlers and side effect functions. When a component subscribes to an Onyx value it never uses for rendering UI, a change to that value re-renders the component without changing anything on screen, which is unnecessary work.

Solution

Expose an Onyx.get() function that can lazily read values from the store

  1. Ship Onyx.get() in react-native-onyx. Onyx.get(key: TKey): Promise<ReadonlyDeep<OnyxValue>> on the public object, implemented on tryGetCachedValue wrapped in afterInit. That is the read useOnyx already performs, and it handles whole collections..
  2. Define where it may be called. Handlers, network callbacks, actions and library helpers whose return value no caller consumes synchronously, useCallback and useEffect bodies among them, since both run on an event. Never a render body, a useOnyx selector, a useMemo body, a useState or useReducer lazy initializer, a useSyncExternalStore snapshot or module scope..
  3. Ban the Search snapshot keys. Our useOnyx wrapper redirects those keys and Onyx.get does not, so it always returns live data and a converted subscription silently changes what a Search-scoped component sees. Scope membership is a runtime property of the mounted tree, so rather than try to decide it, a new lint rule refuses all seven search-overridden keys outright. The ban follows from the redirect, not from anything about the keys themselves. If a future initiative removes snapshot_ and useOnyx wrapper, the rule can be lifted and these high-traffic keys converted..
  4. Enforce it. New lint rule no-unsafe-onyx-read takes every misuse that one file's syntax decides, tsc takes the forgotten await and any attempt to mutate what comes back, and ONYX-1 review takes the rest. Broken down in the thread details..
  5. Prove it on one pilot. useSwitchToDelegator is a great candidate because it has 8 useOnyx subscriptions, none of which are used for rendering. PoC commit.
  6. Convert the easy cases in small PRs. 248 bindings whose value is only used at event time and needs no other change, across 123 files, batched into 19 independent PRs. Details in the thread..
Issue OwnerCurrent Issue Owner: @TaduJR

Activity

  1. chuckdries commented on Sep 22, 2026

    @chuckdries
    ContributorAuthor

    We may also want to do something like https://github.com/Expensify/App/blob/e9cc9d0c696597bf151fa877f7ac74f68c60a18b/.github/workflows/onyxConnectWithoutViewReviewers.yml where we ping a set of reviewers each time a new usage gets added

  2. fabioh8010 commented on Sep 23, 2026

    @fabioh8010
    Contributor

    Hey @chuckdries @tgolen @roryabraham @mountiny based on the lengthy discussion we had in the thread, @LukasMod and I came back with a revised rollout plan so we are all aligned before the next steps.

    Phase 0 — API only

    • Ship Onyx.get without the ReadonlyDeep type for now. Why?
      • In the E/App PR, which has zero migrations, using Onyx.get only in some test files already required ~50 signature changes in ReportUtils plus six other lib files. Any ReadonlyDeep value passed into a lib function typed with our current Onyx types requires changing that function's signature. Every handler in Phase 1 that passes a read value into a lib helper would hit the same thing, so we can't keep readonly and also promise "no lib changes" in the first Phases. I vote for removing it for now and revisiting it per key once we have real usages of Onyx.get in the codebase.
    • In the E/App PR we ship the Onyx bump, no-unsafe-onyx-read, ONYX-1, the docs and the addUtilsToWindow cleanup, with three small additions to the lint rule:
      • Onyx.get is allowed only under src/components, src/pages, src/hooks and tests. Everywhere else is an error.
      • A read inside an effect body is an error for now (see Phase 2).
      • scripts/checkOnyxConnectBypass.ts also covers no-unsafe-onyx-read, so an inline eslint-disable fails CI.
    • In the same PR we also ban OnyxUtils.get too since we have a proper API now.

    Phase 1 — drop-in group, components and hooks

    • The initial 19 PRs described in the proposal, minus reads that would land inside an effect and minus conversions that force a sync consumer to become async (those go to Phase 2 or 3, see below).
    • Every PR is the same edit: delete the useOnyx line and await Onyx.get(key) in the handler that used it. We can start with useSwitchToDelegator, which already has tests written before the conversion. We need to regenerate this list first though, since it was made before the proposal.
    • When these PRs are done we stop and review before going further. We will look at three things: how many useOnyx bindings were removed, whether any of the converted flows regressed, and how many of the ONYX-1 review comments caught real problems vs false alarms (this tells us how much maintenance the new API actually adds). Only then we decide if we continue to Phase 2.

    Phase 2 — the "needs a fix" group and lib replacements
    On the component side, this is the useOnyx usages that are not a straightforward change:

    • Reads inside useEffect. A useOnyx usage can be replaced by Onyx.get inside an effect only if the Onyx value was not in that effect's dependency array. If it was, the subscription is what re-runs the effect and it stays. This is visible in the diff, so it can be a CI check instead of a review judgment.
    • useOnyx calls that use a selector. Onyx.get has no selector option and returns the raw value, so the conversion has to call the selector on the result.
    • Chained keys, where the value of one useOnyx is used to build the key of the next one.
    • Handlers that are consumed synchronously by something that cannot await. These convert in Phase 2 only when the caller can await without changing its own signature. If a chain of callers would have to become async, it goes to Phase 3.

    On the lib side, this is where connectWithoutView gets reduced. Today ~91 of the ~195 connectWithoutView calls only exist to keep a module variable up to date so a function can read it later, nothing reacts to the change. Those can become an await Onyx.get(key) inside that function, but only when the function is already async, or when it returns nothing that a caller uses, so callers can keep calling it without changes. Same rule as above: if callers would have to become async, it goes to Phase 3. To keep this controlled, a lib file only gets added to the allowlist in a PR that also removes a connectWithoutView from that same file, reviewed by the same group that reviews connectWithoutView today. Every approval removes a subscription instead of adding one.

    Phase 3 — reads moving into actions (follow-up work/proposal)

    • The original maintainability idea, e.g. navigateToConciergeChat from 26 call sites to 1, plus every conversion Phases 1 and 2 skipped because it would make a chain of callers async, whether it started as a useOnyx in a component or a connectWithoutView in a lib.
    • Reads only in action creators under src/libs/actions, never in utils, with the render-reachability check running in CI for every converted function.
    • Separate follow-up proposal, with data on how far async actually spreads.
  3. tgolen commented on Sep 23, 2026

    @tgolen
    Contributor

    I'd like to make a small request on the rollout plan. Could we please put the enforcement into place first, before introducing .get() into the code?

  4. LukasMod commented on Sep 24, 2026

    @LukasMod
    Contributor

    I prepared 2 PRs based on @tgolen suggestion and the Phase 0 plan. I dropped the readonly changes to avoid having multiple signatures at this stage.

    I also added one extra thing: Onyx.multiGet for reading multiple keys, which should prevent repetitive Promise.all blocks. Looking back at some previous PoCs, I often migrated multiple keys in a single handler, so it would be nice to have a ready-made method for those cases. WDYT about the idea and the name?

    rn-onyx: Expensify/react-native-onyx#850

    • removed the readonly changes
    • introduced public get / multiGet

    E/App: #102135

    • linked the rn-onyx PR
    • removed the readonly signature changes
    • removed the OnyxUtils.get swap from tests
    • kept only the addUtilsToWindow change, to resolve the get() override conflict
    • added the lint rule, AI reviewer rule, and docs
  5. mountiny commented on Sep 24, 2026

    @mountiny
    Contributor

    Thanks for the update! Lets try to get on C+ for this

  6. changed the title [-]Expose Onyx.get[/-] [+][$1500] Expose Onyx.get[/+] on Sep 24, 2026
  7. melvin-bot commented on Sep 24, 2026

    @melvin-bot

    ⚠️ Could not update price automatically because there is no linked Upwork Job ID. The BZ team member will need to update the price manually in Upwork.

  8. mountiny commented on Sep 24, 2026

    @mountiny
    Contributor

    @LukasMod @fabioh8010 - @aimane-chnaif will be C+ and reviewer on all the prs for this project. Please make sure they are tagged and added on all the prs as I think onyx prs will still autoassign randomly. Also feel free to start threads in Slack for PRs for easier communication so we can deliver this smoothly and sooner than later.

    Thanks!

  9. 25 remaining items

  10. aimane-chnaif commented on Nov 3, 2026

    @aimane-chnaif
    Contributor

    @LukasMod from next PRs, can you please link to this issue (or create sub-issues and assign me) so I can be automatically assigned as reviewer?

    would be great to have one person to review and test the Onyx changes in App + the onyx Bumps and I was elected.

  11. TaduJR commented on Nov 3, 2026

    @TaduJR
    Contributor

    @aimane-chnaif

    I thought you got re-assigned from slack https://expensify.slack.com/archives/C02NK2DQWUX/p1792577119686689?thread_ts=1792576979.553359&cid=C02NK2DQWUX. Could you please double check?

    Thanks

    maybe cc @mountiny

  12. aimane-chnaif commented on Nov 3, 2026

    @aimane-chnaif
    Contributor

    @TaduJR you were assigned only for this PR which had unrelated Onyx changes, not full project

  13. TaduJR commented on Nov 3, 2026

    @TaduJR
    Contributor

    Hmm. I'm not sure how we can get forward. We already have Expensify/react-native-onyx#863, and Expensify/react-native-onyx#884. So we must be in sync with the other coming PRs I though @mountiny assigned for the whole project that's why got dive in to onyx. @mountiny could you decide how should we get forward.

    Thanks!

  14. mountiny commented on Nov 3, 2026

    @mountiny
    Contributor

    @TaduJR no the project has been assigned to @aimane-chnaif

    you had been assigned to help with that one pr linked in Slack that was left behind. I hope that is clear now

  15. added
    ReviewingHas a PR in review
    and removed on Nov 4, 2026
  16. LukasMod commented on Nov 5, 2026

    @LukasMod
    Contributor

    Here’s a more detailed plan for the next PRs. I trimmed keys that don’t change after onboarding, plus a few other rarely changing ones, to keep this phase lean. 22 PRs, at most 10 files each. The first few will tell us how complex they get and whether the split is right. I expect most changes to be mechanical

    Phase 1: PR list

    22 PRs, 380 subscriptions in 172 files. Each PR replaces useOnyx subscriptions that only event handlers use with a one-time Onyx.get / Onyx.multiGet read inside that handler.

    PR 1: src/hooks/useSwitchToDelegator.ts (pilot, open as #105771) (1 file, 8 subscriptions)
    File Handler Onyx keys Note
    hooks/useSwitchToDelegator.ts switchToDelegator ACCOUNT, CREDENTIALS, GPS_DRAFT_DETAILS, NVP_ACTIVE_POLICY_ID, SESSION, STASHED_CREDENTIALS, STASHED_SESSION Already open as #105771: one multiGet in the press handler, the delegatedAccess and GPS-tracking selectors are reapplied after the read.
    PR 2: src/pages/iou (1/3) (10 files, 30 subscriptions)
    File Handler Onyx keys Note
    pages/iou/DynamicSplitBillDetailsPage.tsx onConfirm NVP_QUICK_ACTION_GLOBAL_CREATE
    pages/iou/DynamicSplitExpensePage.tsx onSaveSplitExpense COLLECTION.POLICY_TAGS, COLLECTION.REPORT_DRAFT, COLLECTION.SNAPSHOT, NVP_QUICK_ACTION_GLOBAL_CREATE, RECENTLY_USED_CURRENCIES The existing default is kept with ??.
    pages/iou/RejectReasonPage.tsx onSubmit COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/ParticipantSearchResults.tsx onSelectRow COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/BaseRequestStepWorkspace.tsx selectWorkspace COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/DynamicIOURequestEditReport.tsx removeFromReport CARD_LIST, COLLECTION.POLICY_TAGS, COLLECTION.RULE, PERSONAL_POLICY_ID The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/DynamicIOURequestEditReport.tsx createReport COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read before the handler writes the same key.
    pages/iou/request/step/DynamicIOURequestEditReport.tsx selectReport CARD_LIST, COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/DynamicIOURequestEditReport.tsx createReportForPolicy COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/DynamicIOURequestStepAttendees.tsx saveAttendees COLLECTION.RULE Read after the existing guard, where the value is used.
    pages/iou/request/step/DynamicIOURequestStepCompanyInfo.tsx submit COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_RECENTLY_USED_CATEGORIES, COLLECTION.POLICY_RECENTLY_USED_TAGS, COLLECTION.POLICY_TAGS, RECENTLY_USED_CURRENCIES The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/DynamicIOURequestStepDate.tsx updateDate COLLECTION.RULE, NVP_LAST_SELECTED_DISTANCE_RATES Read before the handler writes the same key.
    pages/iou/request/step/DynamicIOURequestStepDescription.tsx updateComment COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    PR 3: src/pages/iou (2/3) (9 files, 23 subscriptions)
    File Handler Onyx keys Note
    pages/iou/request/step/DynamicIOURequestStepDestination.tsx updateDestination COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END
    pages/iou/request/step/DynamicIOURequestStepDistanceManual.tsx navigateToNextPage COLLECTION.RULE, COLLECTION.SPLIT_TRANSACTION_DRAFT, NVP_LAST_SELECTED_DISTANCE_RATES, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES Read before the handler writes the same key.
    pages/iou/request/step/DynamicIOURequestStepDistanceRate.tsx selectDistanceRate COLLECTION.RULE
    pages/iou/request/step/DynamicIOURequestStepMerchant.tsx updateMerchant COLLECTION.RULE
    pages/iou/request/step/DynamicIOURequestStepTaxAmountPage.tsx updateTaxAmount COLLECTION.RULE
    pages/iou/request/step/DynamicIOURequestStepUpgrade.tsx afterUpgradeAcknowledged CARD_LIST, COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE Read before the handler writes the same key.
    pages/iou/request/step/DynamicIOURequestStepWaypoint.tsx save NVP_RECENT_WAYPOINTS The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/DynamicIOURequestStepWaypoint.tsx selectWaypoint NVP_RECENT_WAYPOINTS The prop expects a synchronous function, so it gets a small wrapper.
    pages/iou/request/step/IOURequestEditReportCommon.tsx handleSelectReport COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read before the handler writes the same key.
    pages/iou/request/step/IOURequestEditReportCommon.tsx loadMoreOutstandingReports HAS_MORE_OUTSTANDING_REPORTS_RESULTS, IS_LOADING_OUTSTANDING_REPORTS Read before the handler writes the same key.
    pages/iou/request/step/IOURequestStepConfirmation/useParticipantPickerState.ts handleParticipantsAdded NVP_LAST_SELECTED_DISTANCE_RATES The prop expects a synchronous function, so it gets a small wrapper.
    PR 4: src/pages/iou (3/3) (7 files, 26 subscriptions)
    File Handler Onyx keys Note
    pages/iou/request/step/IOURequestStepDistance/hooks/useOdometerNavigation.ts returned COLLECTION.RULE, COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_LAST_SELECTED_DISTANCE_RATES, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, NVP_QUICK_ACTION_GLOBAL_CREATE, RECENTLY_USED_CURRENCIES The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    pages/iou/request/step/IOURequestStepDistanceGPS/index.native.tsx navigateToNextStep COLLECTION.RULE, NVP_LAST_SELECTED_DISTANCE_RATES, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES Read before the handler writes the same key.
    pages/iou/request/step/IOURequestStepDistanceOdometer.tsx navigateToNextPage COLLECTION.RULE Read after the existing guard, where the value is used.
    pages/iou/request/step/IOURequestStepHours.tsx onPress COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END
    pages/iou/request/step/IOURequestStepReport/hooks/useReportSelectionActions.ts handleRegularReportSelection CARD_LIST, COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE Read inside the existing deferred callback, not above it.
    pages/iou/request/step/IOURequestStepReport/hooks/useReportSelectionActions.ts removeFromReport CARD_LIST, COLLECTION.POLICY_TAGS, COLLECTION.RULE Read inside the existing deferred callback, not above it.
    pages/iou/request/step/IOURequestStepScan/components/ScanSkipConfirmation.tsx submitDirectly NVP_ACTIVE_POLICY_ID, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES, USER_LOCATION Read before the handler writes the same key.
    pages/iou/request/step/confirmation/submission/useSendMoneySubmission.ts sendMoney NVP_QUICK_ACTION_GLOBAL_CREATE Read inside the existing deferred callback, not above it.
    PR 5: src/pages/workspace (1/3) (8 files, 10 subscriptions)
    File Handler Onyx keys Note
    pages/workspace/ConnectExistingBusinessBankAccountPage.tsx handleItemPress NVP_LAST_PAYMENT_METHOD The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/ConnectExistingBusinessBankAccountPage.tsx handleAddBankAccountPress REIMBURSEMENT_ACCOUNT The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/WorkspaceMoreFeaturesPage/index.tsx onToggle NVP_QUICK_ACTION_GLOBAL_CREATE The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/WorkspaceOverviewPage.tsx handleBackButtonPress IS_COMING_FROM_GLOBAL_REIMBURSEMENTS_FLOW The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/accounting/common/TravelBillingContinuousReconciliationSection.tsx onToggle COLLECTION.TRAVEL_BILLING_CONTINUOUS_RECONCILIATION_CONNECTION
    pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx handleToggleContinuousReconciliation COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/accounting/reconciliation/DynamicReconciliationAccountSettingsPage.tsx selectBankAccount COLLECTION.TRAVEL_BILLING_CONTINUOUS_RECONCILIATION_CONNECTION, COLLECTION.TRAVEL_BILLING_USE_CONTINUOUS_RECONCILIATION Read before the handler writes the same key.
    pages/workspace/companyCards/addNew/CardTypeStep.tsx submit COLLECTION.LAST_SELECTED_FEED The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/companyCards/addNew/CompanyCardsImportedPage.tsx importTransactions COLLECTION.LAST_SELECTED_FEED The prop expects a synchronous function, so it gets a small wrapper.
    PR 6: src/pages/workspace (2/3) (8 files, 11 subscriptions)
    File Handler Onyx keys Note
    pages/workspace/companyCards/addNew/DetailsStep.tsx submit COLLECTION.LAST_SELECTED_FEED Read before the handler writes the same key.
    pages/workspace/companyCards/assignCard/ConfirmationStep.tsx submit COLLECTION.WORKSPACE_CARDS_LIST, COUNTRY
    pages/workspace/copyPolicySettings/CopyPolicySettingsConfirmPage.tsx handleCopyPolicySettings COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE
    pages/workspace/distanceRates/CreateDistanceRatePage.tsx submit COLLECTION.TRANSACTION_DRAFT The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/distanceRates/PolicyDistanceRateGovernmentRateCountryPage.tsx saveCountry GOVERNMENT_MILEAGE_RATES Read after the existing guard, where the value is used.
    pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx toggleAutoUpdateGovernmentRate GOVERNMENT_MILEAGE_RATES Read after the existing guard, where the value is used.
    pages/workspace/downgrade/DynamicWorkspaceDowngradePage.tsx onDowngradeToTeam COLLECTION.POLICY_CATEGORIES Read before the handler writes the same key.
    pages/workspace/expensifyCard/WorkspaceCardsListLabel.tsx requestLimitIncrease IS_LOADING_APP Read after the existing guard, where the value is used.
    PR 7: src/pages/workspace (3/3) (8 files, 12 subscriptions)
    File Handler Onyx keys Note
    pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx startFlow BANK_ACCOUNT_LIST, CARD_SUPPORTED_COUNTRIES
    pages/workspace/expensifyCard/issueNew/ConfirmationStep.tsx handleIssueCard ACCOUNT The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/hr/HRApprovalModePageBase.tsx saveApprovalMode COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS, COLLECTION.RULE Read before the handler writes the same key.
    pages/workspace/hr/HRApprovalModePageBase.tsx confirmSaveApprovalMode COLLECTION.RULE Read before the handler writes the same key.
    pages/workspace/members/WorkspaceInviteMessageComponent.tsx sendInvitation APPROVAL_WORKFLOW Read inside the existing deferred callback, not above it.
    pages/workspace/merge/MergeFinalApproverPageBase.tsx setApprover COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS Read before the handler writes the same key.
    pages/workspace/recruiting/approver/MergeATSApprovalModePage.tsx saveApprovalMode COLLECTION.RULE Read inside the existing deferred callback, not above it.
    pages/workspace/recruiting/approver/MergeATSApprovalModePage.tsx confirmSaveApprovalMode COLLECTION.RULE Read inside the existing deferred callback, not above it.
    pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsCreatePage.tsx createApprovalWorkflow COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/workspace/workflows/tabs/WorkflowsPaymentsTab.tsx handleBankAccountPress CONCIERGE_REPORT_ID, INITIATING_BANK_ACCOUNT_UNLOCK, NVP_INTRO_SELECTED Read after the existing guard, where the value is used.
    PR 8: src/hooks (1/2) (9 files, 35 subscriptions)
    File Handler Onyx keys Note
    hooks/useApplyWorkspaceCurrencyChange.ts returned BANK_ACCOUNT_LIST, CARD_SUPPORTED_COUNTRIES, GOVERNMENT_MILEAGE_RATES, REIMBURSEMENT_ACCOUNT The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    hooks/useBulkDuplicateAction.ts handleDuplicate COLLECTION.RULE, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    hooks/useBulkDuplicateReportAction.ts handleDuplicateReports COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    hooks/useCreateReport.tsx createReport COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, SESSION The prop expects a synchronous function, so it gets a small wrapper.
    hooks/useExpenseActions.ts duplicateExpenseTransaction COLLECTION.POLICY_CATEGORIES, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES Read before the handler writes the same key.
    hooks/useExpenseActions.ts onSelected BANK_ACCOUNT_LIST, COLLECTION.POLICY_CATEGORIES, NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES Read before the handler writes the same key.
    hooks/useHoldMenuSubmit.ts onSubmit BANK_ACCOUNT_LIST, COLLECTION.RULE, COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    hooks/useHoldRejectActions.ts onSelected COLLECTION.RULE, NVP_DISMISSED_HOLD_USE_EXPLANATION, NVP_DISMISSED_REJECT_USE_EXPLANATION
    hooks/useLifecycleActions.tsx onApprove COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    hooks/useLifecycleActions.tsx handleSubmitReport COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    hooks/useMoneyReportHeaderEducationalModals.ts dismissModalAndUpdateUseHold COLLECTION.RULE
    hooks/useMoneyReportHeaderEducationalModals.ts dismissRejectModalBasedOnAction COLLECTION.RULE
    PR 9: src/hooks (2/2) (8 files, 21 subscriptions)
    File Handler Onyx keys Note
    hooks/useReceiptScanDrop.tsx saveFileAndInitMoneyRequest COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, CURRENT_DATE, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read before the handler writes the same key.
    hooks/useRestoreWorkspacesTabOnNavigate.ts returned COLLECTION.DOMAIN The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    hooks/useSaveReportField.ts returned COLLECTION.RULE, RECENTLY_USED_REPORT_FIELDS The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    hooks/useSignOut.ts runLeaveDelegateAccount STASHED_CREDENTIALS, STASHED_SESSION Read before the handler writes the same key.
    hooks/useUndeleteTransactions.ts returned CARD_LIST, COLLECTION.RULE The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    hooks/useUpdateTransactionCategory.ts updateCategory COLLECTION.POLICY_RECENTLY_USED_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE, COLLECTION.SPLIT_TRANSACTION_DRAFT Read after the existing guard, where the value is used.
    hooks/useUpdateTransactionTag.ts updateTag COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_RECENTLY_USED_TAGS, COLLECTION.RULE Read before the handler writes the same key.
    hooks/useUpdateTransactionTaxRate.ts updateTaxRate COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    PR 10: src/pages/settings (1/2) (6 files, 11 subscriptions)
    File Handler Onyx keys Note
    pages/settings/Copilot/CopilotPage.tsx onPress STASHED_CREDENTIALS, STASHED_SESSION Read before the handler writes the same key.
    pages/settings/Rules/RulePageBase.tsx handleSubmit NVP_EXPENSE_RULES The existing default is kept with ??.
    pages/settings/Security/SecuritySettingsPage.tsx action SESSION, STASHED_CREDENTIALS, STASHED_SESSION The existing default is kept with ??.
    pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanCardActionButton.tsx handlePlanPress ACCOUNT
    pages/settings/Subscription/SubscriptionSize/index.tsx onFinished FORMS.SUBSCRIPTION_SIZE_FORM_DRAFT The prop expects a synchronous function, so it gets a small wrapper.
    pages/settings/Wallet/ExpensifyCardPage/index.tsx onPress COUNTRY_CODE, COUNTRY, PRIVATE_PERSONAL_DETAILS The existing default is kept with ??.
    PR 11: src/pages/settings (2/2) (6 files, 17 subscriptions)
    File Handler Onyx keys Note
    pages/settings/Wallet/ImportTransactionsSpreadsheetPage.tsx uploadStatement IMPORTED_SPREADSHEET, NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES
    pages/settings/Wallet/InternationalDepositAccount/subPages/Confirmation.tsx getDataAndGoToNextStep CORPAY_FIELDS Read before the handler writes the same key.
    pages/settings/Wallet/PersonalCardDetailsPage.tsx confirmDeleteCard NVP_SAVED_CSV_COLUMN_LAYOUT_LIST Read inside the existing deferred callback, not above it.
    pages/settings/Wallet/TransactionsImportedPage.tsx importTransactions NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES The prop expects a synchronous function, so it gets a small wrapper.
    pages/settings/Wallet/UpdatePersonalBankAccountPage.tsx submitPersonalInfo COUNTRY_CODE, FORMS.HOME_ADDRESS_FORM_DRAFT, FORMS.PERSONAL_BANK_ACCOUNT_FORM_DRAFT, PRIVATE_PERSONAL_DETAILS The existing default is kept with ??.
    pages/settings/Wallet/WalletPage/index.tsx makeDefaultPaymentMethod COLLECTION.POLICY_MEMBER_BANK_ACCOUNTS
    pages/settings/Wallet/WalletPage/index.tsx confirmDeleteCard NVP_SAVED_CSV_COLUMN_LAYOUT_LIST Read before the handler writes the same key.
    pages/settings/Wallet/WalletPage/index.tsx deletePaymentMethod NVP_LAST_PAYMENT_METHOD, PERSONAL_POLICY_ID Read before the handler writes the same key.
    pages/settings/Wallet/WalletPage/index.tsx paymentMethodPressed COLLECTION.NVP_LOCKED_VBA_UNLOCK_REQUESTED, CONCIERGE_REPORT_ID, INITIATING_BANK_ACCOUNT_UNLOCK, NVP_INTRO_SELECTED Read before the handler writes the same key.
    PR 12: src/pages/inbox (1/2) (7 files, 15 subscriptions)
    File Handler Onyx keys Note
    pages/inbox/report/ContextMenu/PopoverReportActionContextMenu.tsx confirmDeleteAndHideModal BANK_ACCOUNT_LIST, DERIVED.VISIBLE_REPORT_ACTIONS The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx selectOption COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read inside the existing deferred callback, not above it.
    pages/inbox/report/ReportActionCompose/useComposerSubmit.ts validateAndSubmitDraft CONCIERGE_REPORT_ID, NVP_QUICK_ACTION_GLOBAL_CREATE The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/report/ReportActionCompose/useComposerSubmit.ts submitDraftAndClearComposer COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE Read before the handler writes the same key.
    pages/inbox/report/ReportActionCompose/useReceiptDrop.ts onFilesValidated CURRENT_DATE Read before the handler writes the same key.
    pages/inbox/report/ReportActionCompose/useReceiptDrop.ts onReceiptDropped COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/sidebar/FABPopoverContent/menuItems/CreateReportMenuItem.tsx handleCreateWorkspaceReport COLLECTION.RULE Read inside the existing deferred callback, not above it.
    pages/inbox/sidebar/FABPopoverContent/menuItems/ExpenseMenuItem.tsx onPress SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/sidebar/FABPopoverContent/menuItems/InvoiceMenuItem.tsx onPress SESSION The prop expects a synchronous function, so it gets a small wrapper.
    PR 13: src/pages/inbox (2/2) (6 files, 13 subscriptions)
    File Handler Onyx keys Note
    pages/inbox/sidebar/FABPopoverContent/menuItems/NewChatMenuItem.tsx onPress SESSION Read after the existing guard, where the value is used.
    pages/inbox/sidebar/FABPopoverContent/menuItems/NewWorkspaceMenuItem.tsx onPress SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/sidebar/FABPopoverContent/menuItems/QuickActionMenuItem.tsx onPress COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_LAST_DISTANCE_EXPENSE_TYPE, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, SESSION Read before the handler writes the same key.
    pages/inbox/sidebar/FABPopoverContent/menuItems/QuickActionMenuItem.tsx selectOption COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read before the handler writes the same key.
    pages/inbox/sidebar/FABPopoverContent/menuItems/TrackDistanceMenuItem.tsx onPress SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/sidebar/FABPopoverContent/menuItems/TravelMenuItem.tsx onPress SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/sidebar/FABPopoverContent/useScanActions.ts startScan SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/inbox/sidebar/FABPopoverContent/useScanActions.ts startQuickScan COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, SESSION The prop expects a synchronous function, so it gets a small wrapper.
    PR 14: src/pages/Search (9 files, 19 subscriptions)
    File Handler Onyx keys Note
    pages/Search/EmptySearchView.tsx handleCreateMoneyRequest SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/EmptySearchView.tsx handleCreateWorkspaceReport COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/SearchApproverPage.tsx addApprover COLLECTION.RULE
    pages/Search/SearchEditMultiple/SearchEditMultiplePage.tsx commit COLLECTION.RAM_ONLY_POLICY_TAGS_LOADING_STATE Read inside the existing deferred callback, not above it.
    pages/Search/SearchHoldReasonPage.tsx onSubmit COLLECTION.RULE Read inside the existing deferred callback, not above it.
    pages/Search/SearchRejectReasonPage.tsx onSubmit COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/SearchReportsMergeReports.tsx mergeSelectedReports BANK_ACCOUNT_LIST, CARD_LIST, COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS Read before the handler writes the same key.
    pages/Search/SearchTransactionsChangeReport.tsx createReportForPolicy COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/SearchTransactionsChangeReport.tsx selectReport COLLECTION.POLICY_CATEGORIES, COLLECTION.POLICY_TAGS, COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/SearchTransactionsChangeReport.tsx removeFromReport COLLECTION.POLICY_TAGS, COLLECTION.RULE, PERSONAL_POLICY_ID The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/SearchTransactionsChangeReport.tsx createReport COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read after the existing guard, where the value is used.
    pages/Search/SearchTypeMenuNarrow.tsx handleTabPress SEARCH_FILTERS The prop expects a synchronous function, so it gets a small wrapper.
    pages/Search/SearchTypeMenuWide.tsx arg of singleExecution() SEARCH_FILTERS The prop expects a synchronous function, so it gets a small wrapper.
    PR 15: src/pages (other) (1/4) (9 files, 30 subscriptions)
    File Handler Onyx keys Note
    pages/AddExistingExpense.tsx buttonAction COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/DynamicNewReportWorkspaceSelectionPage.tsx createReport CARD_LIST, COLLECTION.POLICY_TAGS, COLLECTION.RULE, NVP_ACTIVE_POLICY_ID The existing default is kept with ??.
    pages/DynamicNewReportWorkspaceSelectionPage.tsx selectPolicy COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END Read after the existing guard, where the value is used.
    pages/DynamicReportChangeApproverPage.tsx changeApprover COLLECTION.RULE The prop expects a synchronous function, so it gets a small wrapper.
    pages/DynamicReportChangeWorkspacePage.tsx selectPolicy COLLECTION.RULE, COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    pages/DynamicReportDetailsPage/ReportDetailsMenuLeaveItem.tsx leaveChat CONCIERGE_REPORT_ID, DERIVED.GUIDE_ACCOUNT_IDS, NVP_INTRO_SELECTED, NVP_QUICK_ACTION_GLOBAL_CREATE Read before the handler writes the same key.
    pages/DynamicReportDetailsPage/ReportDetailsTaskDeleteAction.tsx deleteTransaction CONCIERGE_REPORT_ID, DERIVED.GUIDE_ACCOUNT_IDS Read inside the existing deferred callback, not above it.
    pages/EnablePayments/Wallet/AddBankAccount/AddBankAccount.tsx submit FORMS.WALLET_ADDITIONAL_DETAILS_DRAFT, PERSONAL_POLICY_ID, PLAID_DATA, PRIVATE_PERSONAL_DETAILS, WALLET_ADDITIONAL_DETAILS Read before the handler writes the same key.
    pages/EnablePayments/Wallet/AddBankAccount/AddBankAccount.tsx exitFlow PERSONAL_BANK_ACCOUNT The prop expects a synchronous function, so it gets a small wrapper.
    pages/EnablePayments/Wallet/FeesAndTerms/FeesAndTerms.tsx submit WALLET_TERMS Read inside the existing deferred callback, not above it.
    pages/EnablePayments/shared/useWalletPhoneValidateCode.ts submitPersonalDetails PRIVATE_PERSONAL_DETAILS The prop expects a synchronous function, so it gets a small wrapper.
    PR 16: src/pages (other) (2/4) (9 files, 12 subscriptions)
    File Handler Onyx keys Note
    pages/MissingPersonalDetails/MissingPersonalDetailsContent.tsx handleFinishStep COUNTRY_CODE The prop expects a synchronous function, so it gets a small wrapper.
    pages/OnboardingPersonalTrackGoal/BaseOnboardingPersonalTrackGoal.tsx completeTrackGoalSelection FORMS.ONBOARDING_PERSONAL_DETAILS_FORM
    pages/OnboardingPurpose/BaseOnboardingPurpose.tsx onPress FORMS.ONBOARDING_PERSONAL_DETAILS_FORM, NVP_INTRO_SELECTED, ONBOARDING_COMPANY_SIZE, ONBOARDING_POLICY_ID Read after the existing guard, where the value is used.
    pages/OnboardingWorkEmailValidation/BaseOnboardingWorkEmailValidation.tsx sendValidateCode CREDENTIALS The prop expects a synchronous function, so it gets a small wrapper.
    pages/ReimbursementAccount/EnterSignerInfo/index.tsx submit FORMS.ENTER_SINGER_INFO_FORM_DRAFT The prop expects a synchronous function, so it gets a small wrapper.
    pages/ReimbursementAccount/ReimbursementAccountPage.tsx goBack ONFIDO_TOKEN The prop expects a synchronous function, so it gets a small wrapper.
    pages/ReimbursementAccount/USD/CompleteVerification/CompleteVerification.tsx submit NVP_LAST_PAYMENT_METHOD The prop expects a synchronous function, so it gets a small wrapper.
    pages/ReimbursementAccount/USD/Requestor/VerifyIdentity/VerifyIdentity.tsx handleOnfidoSuccess ONFIDO_APPLICANT_ID
    pages/RejectExpenseReportPage.tsx onSubmit COLLECTION.RULE
    PR 17: src/pages (other) (3/4) (9 files, 14 subscriptions)
    File Handler Onyx keys Note
    pages/ReportAddApproverPage.tsx addApprover COLLECTION.RULE
    pages/ReportReassignApproverPage.tsx save COLLECTION.RULE
    pages/ReportSubmitToContent.tsx handleSubmit COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    pages/SetDefaultWorkspacePage.tsx selectPolicy NVP_ACTIVE_POLICY_ID The existing default is kept with ??.
    pages/Share/SubmitDetailsPage.tsx onConfirm NVP_LAST_LOCATION_PERMISSION_PROMPT The prop expects a synchronous function, so it gets a small wrapper.
    pages/TransactionDuplicate/DynamicReviewPage.tsx onPreviewPressed TRANSACTION_THREAD_NAVIGATION_SNAPSHOT_HASH, TRANSACTION_THREAD_NAVIGATION_THREAD_REPORT_IDS, TRANSACTION_THREAD_NAVIGATION_TRANSACTION_IDS
    pages/TransactionDuplicate/DynamicReviewPage.tsx keepAll COLLECTION.RULE
    pages/TransactionMerge/DynamicConfirmationPage.tsx mergeExpenses COLLECTION.RULE
    pages/Travel/DynamicTripDetailsPage.tsx onPress NVP_ACTIVE_POLICY_ID
    pages/Travel/EnableTravel/subPages/TermsStep.tsx createTravelEnablementIssue ACCOUNT Read after the existing guard, where the value is used.
    PR 18: src/pages (other) (4/4) (7 files, 11 subscriptions)
    File Handler Onyx keys Note
    pages/domain/DomainsListPage.tsx onPress SESSION
    pages/home/ForYouSection/ConciergePromptBox.tsx sendAttachment SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/home/ForYouSection/ConciergePromptBox.tsx submit SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/home/ForYouSection/ConciergePromptBox.tsx onPress SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/home/ForYouSection/ConciergePromptBox.tsx onPasteFile SESSION The prop expects a synchronous function, so it gets a small wrapper.
    pages/home/TimeSensitiveSection/items/UnlockBankAccount.tsx handleCtaPress COLLECTION.NVP_LOCKED_VBA_UNLOCK_REQUESTED, CONCIERGE_REPORT_ID, INITIATING_BANK_ACCOUNT_UNLOCK, NVP_INTRO_SELECTED Read before the handler writes the same key.
    pages/signin/ChooseSSOOrValidateCode.tsx onPress CREDENTIALS Read before the handler writes the same key.
    pages/signin/SignUpWelcomeForm.tsx onPress MARKETING_ATTRIBUTION, NVP_PREFERRED_LOCALE
    pages/tasks/DynamicNewTaskDetailsPage.tsx onSubmit NVP_QUICK_ACTION_GLOBAL_CREATE Read before the handler writes the same key.
    pages/tasks/DynamicNewTaskPage.tsx onSubmit NVP_QUICK_ACTION_GLOBAL_CREATE The prop expects a synchronous function, so it gets a small wrapper.
    PR 19: src/components (1/4) (9 files, 24 subscriptions)
    File Handler Onyx keys Note
    components/AccountSwitcherButton.tsx onSelected CREDENTIALS, NVP_ACTIVE_POLICY_ID, SESSION The prop expects a synchronous function, so it gets a small wrapper.
    components/AddExistingExpenseFooter.tsx handleConfirm CARD_LIST, COLLECTION.RULE, NVP_QUICK_ACTION_GLOBAL_CREATE, RECENTLY_USED_CURRENCIES Read inside the existing deferred callback, not above it.
    components/FloatingCameraButton/BaseFloatingCameraButton.tsx onPress COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END, SESSION The prop expects a synchronous function, so it gets a small wrapper.
    components/ImportOnyxState/index.native.tsx handleFileRead ACCOUNT, SESSION Read inside the existing deferred callback, not above it.
    components/ImportOnyxState/index.tsx handleFileRead ACCOUNT, SESSION The prop expects a synchronous function, so it gets a small wrapper.
    components/ImportSpreadsheet.tsx readFile IMPORTED_SPREADSHEET Read inside the existing deferred callback, not above it.
    components/MoneyReportHeaderPrimaryAction/RemoveHoldPrimaryAction.tsx onPress COLLECTION.RULE Read after the existing guard, where the value is used.
    components/MoneyReportHeaderPrimaryAction/SubmitPrimaryAction.tsx handleSubmit COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    components/MoneyReportHeaderPrimaryAction/useConfirmApproval.ts onApprove COLLECTION.RULE, COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    PR 20: src/components (2/4) (9 files, 14 subscriptions)
    File Handler Onyx keys Note
    components/MoneyRequestConfirmationList/sections/AmountField.tsx buildAndSaveSplitShares COLLECTION.SPLIT_TRANSACTION_DRAFT The prop expects a synchronous function, so it gets a small wrapper.
    components/MoneyRequestConfirmationList/sections/DateField.tsx handleDateChange COLLECTION.SPLIT_TRANSACTION_DRAFT, NVP_LAST_SELECTED_DISTANCE_RATES Read before the handler writes the same key.
    components/MoneyRequestConfirmationList/sections/DescriptionField.tsx handleDescriptionInputChange COLLECTION.SPLIT_TRANSACTION_DRAFT
    components/MoneyRequestConfirmationList/sections/MerchantField.tsx handleMerchantInputChange COLLECTION.SPLIT_TRANSACTION_DRAFT Read after the existing guard, where the value is used.
    components/MoneyRequestConfirmationList/sections/TaxFields.tsx handleTaxAmountChange COLLECTION.SPLIT_TRANSACTION_DRAFT
    components/MoneyRequestHeaderSecondaryActions.tsx duplicateTransaction NVP_QUICK_ACTION_GLOBAL_CREATE, NVP_RECENT_WAYPOINTS, RECENTLY_USED_CURRENCIES The existing default is kept with ??.
    components/MoneyRequestReportView/SearchMoneyRequestReportEmptyState.tsx onSelected COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END
    components/Navigation/AccountAvatarButton.tsx navigateToAccount SESSION
    components/Navigation/DebugTabView.tsx navigateTo REIMBURSEMENT_ACCOUNT Read before the handler writes the same key.
    PR 21: src/components (3/4) (9 files, 14 subscriptions)
    File Handler Onyx keys Note
    components/Navigation/NavigationTabBar/InsightsTabButton.tsx navigateToInsights SESSION
    components/Navigation/NavigationTabBar/SearchTabButton.tsx navigateToSearch REPORT_NAVIGATION_LAST_SEARCH_QUERY, SESSION
    components/Navigation/NavigationTabBar/index.tsx navigateToSettings SESSION The prop expects a synchronous function, so it gets a small wrapper.
    components/Navigation/QuickCreationActionsBar/index.tsx handleDistance NVP_LAST_DISTANCE_EXPENSE_TYPE Read before the handler writes the same key.
    components/Navigation/QuickCreationActionsBar/index.tsx handleCreateWorkspaceReport COLLECTION.RULE Read inside the existing deferred callback, not above it.
    components/Reactions/ReportActionItemEmojiReactions.tsx onPress PREFERRED_EMOJI_SKIN_TONE The prop expects a synchronous function, so it gets a small wrapper.
    components/ReportActionItem/MoneyRequestReportPreview/useConfirmApproveReportAction.ts returned COLLECTION.RULE The hook returns this handler; it stays synchronous for callers through a wrapper inside the hook.
    components/Search/FilterComponents/AdvancedFilters/SearchNLFilterContent.tsx handleSubmit NVP_ACTIVE_POLICY_ID
    components/Search/SearchBulkActionsButton.tsx payBulkSelectedItem BANK_ACCOUNT_LIST, COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END, NVP_PRIVATE_AMOUNT_OWED, NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END The prop expects a synchronous function, so it gets a small wrapper.
    components/Search/SearchList/ListItem/TransactionGroupListExpanded.tsx handleOnPress RAM_ONLY_MOBILE_SELECTION_MODE
    PR 22: src/components (4/4) (9 files, 10 subscriptions)
    File Handler Onyx keys Note
    components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx onSelected SESSION
    components/Search/SearchPageHeader/SearchActionsBarCreateButton.tsx handleCreateWorkspaceReport COLLECTION.RULE Read inside the existing deferred callback, not above it.
    components/Search/SearchRouter/useAskConcierge.tsx askConcierge NVP_QUICK_ACTION_GLOBAL_CREATE
    components/Search/SearchRouter/useCreateNavigationSuggestions.ts onCreateReport COLLECTION.RULE Read inside the existing deferred callback, not above it.
    components/Search/hooks/useUpdateFilterQuery.tsx setFilterQueryParams FORMS.SEARCH_ADVANCED_FILTERS_FORM Read inside the existing deferred callback, not above it.
    components/Search/hooks/useUpdateFilterQuery.tsx updateFilterQueryParams FORMS.SEARCH_ADVANCED_FILTERS_FORM Read inside the existing deferred callback, not above it.
    components/SignInButtons/AppleSignIn/index.android.tsx handleSignIn NVP_PREFERRED_LOCALE Read before the handler writes the same key.
    components/SignInButtons/AppleSignIn/index.ios.tsx handleSignIn NVP_PREFERRED_LOCALE The prop expects a synchronous function, so it gets a small wrapper.
    components/SignInButtons/GoogleSignIn/index.native.tsx onPress NVP_PREFERRED_LOCALE
    components/Tables/WorkspaceCompanyCardsTable/WorkspaceCompanyCardsTableHeaderButtons.tsx openBankConnection COUNTRY
    components/ValidateCode/ValidateCodeModal.tsx signInHere NVP_PREFERRED_LOCALE The prop expects a synchronous function, so it gets a small wrapper.
  17. LukasMod commented on Nov 10, 2026

    @LukasMod
    Contributor

    I plan to start working on the next planned PRs over the coming days. I'll be OOO on November 11 due to a national public holiday.

    Update:

  18. melvin-bot commented on Nov 11, 2026

    @melvin-bot

    @TaduJR / @aimane-chnaif

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.35-3 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

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

Metadata

Metadata

Labels

DailyKSv2ImprovementItem broken or needs improvement.Skip PaymentSkips all the payment process steps for an issue. Use it for fixed-price projects.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions