Skip to content

[Payment due @mkhutornyi] Fire OpenApp without chained promise - #94121

Merged
mountiny merged 12 commits into
Expensify:mainfrom
s77rt:fire-openapp-without-chained-promise
Jun 29, 2026
Merged

[Payment due @mkhutornyi] Fire OpenApp without chained promise#94121
mountiny merged 12 commits into
Expensify:mainfrom
s77rt:fire-openapp-without-chained-promise

Conversation

@s77rt

@s77rt s77rt commented Jun 20, 2026

Copy link
Copy Markdown
Member

Explanation of Change

On login, we call openApp() from AuthScreensInitHandler's useEffect since it's the first mounted screen, then we may call search() from YourSpendSection's useYourSpendData when we load the home page. Although this seems correct, the actual requests order may not be OpenApp->Search because the openApp() function does not initiate the request instantly instead it does so after a promise is resolved and since that's done asynchronously, it will often get called after search() making the order Search->OpenApp. This is a problem because OpenApp may overwrite data that was returned by Search.

In this PR I have removed the chained promise and now openApp() will initiate the http call instantly and that would preserve the expected order OpenApp->Search.

Also: I have removed the isReadyToOpenApp promise since it's a promise and conflicts with the changes here. That promise was added here #18114 to $ #18115 and I think it is not doing anything at this point as after singing in I got redirected to Home (with and without the promise).

Fixed Issues

https://github.com/Expensify/Expensify/issues/643382
PROPOSAL:

Tests

  1. Log in to an existing account (that have at least some reports pending submit, approve, or pay)
  2. Watch the Network tab
  3. Verify we fire OpenApp request before any Search requests
Before After
Screen.Recording.2026-06-20.at.7.10.32.PM.mov
Screen.Recording.2026-06-20.at.7.21.39.PM.mov
  • Verify that no errors appear in the JS console

Offline tests

n/a

QA Steps

Same as Tests.

  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari

@s77rt
s77rt marked this pull request as ready for review June 20, 2026 18:34
@s77rt
s77rt requested review from a team as code owners June 20, 2026 18:34
@melvin-bot
melvin-bot Bot requested review from flaviadefaria and madmax330 and removed request for a team June 20, 2026 18:34
@melvin-bot

melvin-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown

@madmax330 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@s77rt
s77rt requested review from luacmartins and mountiny and removed request for madmax330 June 20, 2026 18:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ef81897a44

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/libs/actions/App.ts
Comment on lines +311 to +312
function getPolicyParamsForOpenOrReconnect(): PolicyParamsForOpenOrReconnect {
return {policyIDList: getNonOptimisticPolicyIDs(allPolicies)};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve policy IDs when opening the app

When openApp()/reconnectApp() runs before this module-level policy subscription has delivered its first collection callback (for example during cold start, sign-in, or after clearing Onyx while switching accounts), allPolicies is still undefined, so this returns policyIDList: [] and the queued OpenApp/ReconnectApp request is never corrected after policies hydrate. The previous per-call connectWithoutView(...waitForCollectionCallback...) waited for the current policy collection before building the request, so existing workspace policy IDs were sent reliably; without them the server cannot include/update data scoped to those cached policies on the initial sync.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a real problem. If we have not loaded the policies in the module level by the time we call this then we probably have nothing to load. I think this is mostly needed for ReconnectApp and it does look to work fine on page refresh.

@s77rt s77rt changed the title Fire OpenApp without chained promise Fire OpenApp without Onyx chained promise Jun 20, 2026
@s77rt s77rt changed the title Fire OpenApp without Onyx chained promise Fire OpenApp without chained promise Jun 20, 2026
Comment thread src/libs/actions/App.ts
function triggerFullReconnect(cutoff: string) {
Onyx.merge(ONYXKEYS.LAST_FULL_RECONNECT_TIME, getLastFullReconnectTimeToRecord(cutoff));
reconnectApp();
Onyx.merge(ONYXKEYS.LAST_FULL_RECONNECT_TIME, getLastFullReconnectTimeToRecord(cutoff)).then(() => reconnectApp());

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed because before the changes in this PR, reconnectApp already had a promise that it was waiting for and by the time it resolves the onyx value would have been updated already.

Now, since this reconnectApp call happens instantly we need to explicitly wait here before reconnect app

@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ Changes either increased or maintained existing code coverage, great job!

Files with missing lines Coverage Δ
src/DelegateAccessHandler.tsx 93.33% <ø> (ø)
src/libs/actions/Delegate.ts 31.28% <ø> (+0.51%) ⬆️
src/libs/actions/Reconnect.ts 100.00% <100.00%> (ø)
src/pages/ConciergePage.tsx 0.00% <ø> (ø)
src/pages/Search/SearchPage.tsx 85.71% <ø> (ø)
src/pages/SubmitExpensePage.tsx 0.00% <ø> (ø)
src/pages/TrackExpensePage.tsx 0.00% <ø> (ø)
src/pages/domain/DomainInitialPage.tsx 0.00% <ø> (ø)
src/pages/home/HomePage.tsx 100.00% <ø> (ø)
src/pages/inbox/sidebar/BaseSidebarScreen.tsx 100.00% <ø> (ø)
... and 4 more
... and 28 files with indirect coverage changes

@s77rt
s77rt requested a review from mkhutornyi June 20, 2026 20:06
@s77rt

s77rt commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

@mkhutornyi When testing this, can you also please test #18115 in main and in this branch and confirm if we have a different behavior. Ideally, you should land on the room report but if you landed on Home on both branches that may be okay (as long as we are not causing a regression here)

@mountiny

Copy link
Copy Markdown
Contributor

@codex review

@mountiny

Copy link
Copy Markdown
Contributor

@MelvinBot Review

@MelvinBot

Copy link
Copy Markdown
Contributor

Review

The approach is sound and correctly targets the root cause. Firing OpenApp synchronously (removing the getPolicyParamsForOpenOrReconnect promise chain) guarantees it is enqueued before Search, since both API.write* calls now enqueue in call order and openApp() is invoked first (from AuthScreensInitHandler) before useYourSpendData's search(). Checks are green, references are fully cleaned up, and tests were updated consistently.

Two things worth confirming before merge:

1. Removing the isReadyToOpenApp / confirmReadyToOpenApp gate — highest-risk change. That gate (added in #18114 for #18115) deliberately delayed the OpenApp/ReconnectApp HTTP request until a UI entry point signalled readiness, so the navigation data in the response landed after the target screen was mounted. Removing it means the request now fires before any page mounts. The PR body says sign-in still lands on Home, but deeplink-into-a-report (the original #18115 scenario) is exactly the case the gate protected. mountiny's comment already asks the tester to verify #18115 on both branches — that QA result is the real gate for this PR, so please make sure it's confirmed (deeplink to a report, and reload while on a deep report URL) rather than relying on the Home redirect alone.

2. Module-level allPolicies timing (the Codex P1 at App.ts:303). s77rt's rebuttal is reasonable: this mirrors the existing allReports pattern, reconnectApp still waits on hasLoadedAppPromise before reading policies, and on a cold login there are no cached policies to send anyway. The only residual window is a warm start / account-switch where openApp() (which now fires synchronously) runs before the POLICY collection callback has populated allPolicies, yielding policyIDList: []. Low risk and consistent with allReports, but worth a quick sanity check on a refresh/account-switch with cached workspaces to confirm policyIDList is non-empty in the OpenApp request.

The triggerFullReconnect change to Onyx.merge(...).then(() => reconnectApp()) is correct and necessary — with the synchronous path the LAST_FULL_RECONNECT_TIME merge must complete before reconnectApp reads it, matching the function's documented "record first" guarantee.

Minor nit

tests/ui/SessionTest.tsx:99-100 still has an explanatory comment referencing "an isReadyToOpenApp gate" that no longer exists after this PR. The mock itself is fine; just a stale comment.

Nothing here blocks merge from a code-correctness standpoint — the implementation is clean. The decision hinges on the #18115 QA confirmation in point 1.

@mountiny
mountiny requested a review from adhorodyski June 21, 2026 11:33
@mountiny

Copy link
Copy Markdown
Contributor

@adhorodyski Could you please review as well since you had been working in this area recently so it will be helpful to get your view as well. Thanks!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b1a8ce2d1c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/libs/actions/App.ts
@adhorodyski

Copy link
Copy Markdown
Contributor

My first feedback is that this looks like a big correctness update so 👍🏼 I don't see any pain points and things that could break with it, it does not really touch the SQ or any other ordering mechanisms.

Comment on lines -48 to -50
if (isLoadingApp) {
Log.info('[Reconnect] App is still loading, calling openApp');
openApp();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not correct. If we are loading app (OpenApp in progress) then we should not queue another OpenApp call.

If the app is not loaded, reconnectApp will actually call OpenApp (already handled in the call itself), otherwise we will call reconnectApp normally

@s77rt

s77rt commented Jun 25, 2026

Copy link
Copy Markdown
Member Author

Should be fixed now. @mkhutornyi Can you please confirm the same

Comment on lines -46 to -66
test('calls openApp when isLoadingApp is true', async () => {
await Onyx.merge(ONYXKEYS.SESSION, {accountID: 1234, email: 'test@test.com'});
await Onyx.merge(ONYXKEYS.IS_LOADING_APP, true);
await waitForBatchedUpdates();

reconnect();

expect(jest.mocked(openApp)).toHaveBeenCalledTimes(1);
expect(jest.mocked(reconnectApp)).not.toHaveBeenCalled();
});

test('calls reconnectApp when isLoadingApp is false', async () => {
await Onyx.merge(ONYXKEYS.SESSION, {accountID: 1234, email: 'test@test.com'});
await Onyx.merge(ONYXKEYS.IS_LOADING_APP, false);
await waitForBatchedUpdates();

reconnect();

expect(jest.mocked(reconnectApp)).toHaveBeenCalledTimes(1);
expect(jest.mocked(openApp)).not.toHaveBeenCalled();
});

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no longer relevant. Whether the app is loading or not, we will always call reconnectApp, we will never queue OpenApp on top of another existing OpenApp.

@mkhutornyi

Copy link
Copy Markdown
Contributor

Still same. This is log after fresh install and creating new account:

Screenshot 2026-06-26 at 5 47 35 AM

@mountiny

Copy link
Copy Markdown
Contributor

@s77rt @mkhutornyi we merged this PR #94210 yesterday, can you check if it does not fix your issue by any chance?

@s77rt

s77rt commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

@mkhutornyi I was not able to reproduce. Can you please check again and verify that you synced the branch

Screen.Recording.2026-06-26.at.2.35.46.PM.mov

Before testing, please apply this diff to see which openApp is firing the requests

Details
diff --git a/src/DelegateAccessHandler.tsx b/src/DelegateAccessHandler.tsx
index 62005f45c73..d1d48d9a023 100644
--- a/src/DelegateAccessHandler.tsx
+++ b/src/DelegateAccessHandler.tsx
@@ -68,6 +68,7 @@ function DelegateAccessHandler() {
             sessionAccountID,
             hasLoadedApp: !!hasLoadedApp,
         });
+        console.log('openApp A');
         openApp();
     }, [hasLoadedApp, isLoadingApp, isOffline, sessionAccountID, isLoadingAppMetadata]);
 
diff --git a/src/components/OpenAppFailureModal/index.native.tsx b/src/components/OpenAppFailureModal/index.native.tsx
index 3e81764cce7..e53d63a27d5 100644
--- a/src/components/OpenAppFailureModal/index.native.tsx
+++ b/src/components/OpenAppFailureModal/index.native.tsx
@@ -7,6 +7,7 @@ import BaseOpenAppFailureModal from './BaseOpenAppFailureModal';
 /** Triggers OpenApp reconnection */
 const retryOpenApp = () => {
     setIsOpenAppFailureModalOpen(false);
+    console.log('openApp B');
     openApp();
 };
 
diff --git a/src/libs/Navigation/AppNavigator/AuthScreensInitHandler.tsx b/src/libs/Navigation/AppNavigator/AuthScreensInitHandler.tsx
index 7eb752147fe..c82399d6838 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreensInitHandler.tsx
+++ b/src/libs/Navigation/AppNavigator/AuthScreensInitHandler.tsx
@@ -125,6 +125,7 @@ function AuthScreensInitHandler() {
                 // Don't want to call `openReport` again when logging out and then logging in
                 setIsAuthenticatedAtStartup(true);
             }
+            console.log('openApp M');
             App.openApp();
         } else {
             Log.info('[AuthScreens] Sending ReconnectApp');
diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts
index da6befbc02e..a10fd8d2c14 100644
--- a/src/libs/actions/App.ts
+++ b/src/libs/actions/App.ts
@@ -481,6 +481,7 @@ function reconnectApp(updateIDFrom: OnyxEntry<number> = 0) {
             if (bootsplashSpan) {
                 endSpan(CONST.TELEMETRY.SPAN_NAVIGATION.APP_OPEN);
             }
+            console.log('openApp C');
             openApp();
             return;
         }
diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts
index 6f785504214..0fe2112846b 100644
--- a/src/libs/actions/Delegate.ts
+++ b/src/libs/actions/Delegate.ts
@@ -218,6 +218,7 @@ function connect({email, delegatedAccess, credentials, session, activePolicyID,
                     return clearOnyxForDelegateTransition();
                 })
                 .then(() => {
+                    console.log('openApp D');
                     return openApp().then(() => {
                         if (!CONFIG.IS_HYBRID_APP || !policyID) {
                             return true;
@@ -322,6 +323,7 @@ function disconnect({stashedCredentials, stashedSession}: DisconnectParams) {
                     });
                     Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, {});
                     Onyx.set(ONYXKEYS.STASHED_SESSION, {});
+                    console.log('openApp E');
                     openApp().then(() => {
                         if (!CONFIG.IS_HYBRID_APP) {
                             return;
@@ -760,6 +762,7 @@ function restoreDelegateSession<TKey extends OnyxKey>(authenticateResponse: Resp
         NetworkStore.setAuthToken(authenticateResponse.authToken ?? null);
         NetworkStore.setIsAuthenticating(false);
 
+        console.log('openApp F');
         openApp();
     });
 }
diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts
index acf9a58748b..6edca69d706 100644
--- a/src/libs/actions/Session/index.ts
+++ b/src/libs/actions/Session/index.ts
@@ -466,6 +466,7 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess
                         Onyx.set(ONYXKEYS.STASHED_CREDENTIALS, {});
                         Onyx.set(ONYXKEYS.STASHED_SESSION, {});
 
+                        console.log('openApp H');
                         openApp();
 
                         if (CONFIG.IS_HYBRID_APP && hasSwitchedAccountInHybridMode) {
@@ -483,6 +484,7 @@ function signOutAndRedirectToSignIn(shouldResetToHome?: boolean, shouldStashSess
                     Onyx.multiSet(onyxSetParams);
 
                     if (hasSwitchedAccountInHybridMode) {
+                        console.log('openApp I');
                         openApp();
                     }
                 });
@@ -713,6 +715,7 @@ function setupNewDotAfterTransitionFromOldDot(hybridAppSettings: HybridAppSettin
             // Just update the session and credentials without clearing
             if (isUsingImportedState) {
                 Log.info('[HybridApp] Skipping Onyx clear because using imported state. Updating session only.');
+                console.log('openApp J');
                 return Onyx.multiSet({
                     ...stashedData,
                     [ONYXKEYS.SESSION]: {
@@ -731,6 +734,7 @@ function setupNewDotAfterTransitionFromOldDot(hybridAppSettings: HybridAppSettin
             }
 
             Log.info('[HybridApp] User switched account on OldDot side. Clearing onyx and applying delegate data');
+            console.log('openApp K');
             return clearOnyxForDelegateTransition()
                 .then(() =>
                     Onyx.multiSet({
@@ -1293,6 +1297,7 @@ function updateAuthTokenAndOpenApp(authToken?: string, encryptedAuthToken?: stri
     // enough to do the updateSessionAuthTokens() call above.
     NetworkStore.setAuthToken(authToken ?? null);
 
+    console.log('openApp L');
     openApp();
 }
 

@s77rt

s77rt commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

@mountiny I merged main yesterday and that change is included

@mkhutornyi

Copy link
Copy Markdown
Contributor

@s77rt here's full video with logs:

Screen.Recording.2026-06-26.at.4.12.12.PM.mov

@mkhutornyi

Copy link
Copy Markdown
Contributor

Actually, it behaves the same in production (main branch) so I won't block on this.

@melvin-bot melvin-bot Bot changed the title Fire OpenApp without chained promise [Payment due @mkhutornyi] Fire OpenApp without chained promise Jun 26, 2026
@melvin-bot

melvin-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

🎯 @mkhutornyi, thanks for reviewing and testing this PR! 🎉

A payment issue will be created for your review once this PR is deployed to production.
E/E issue linked to the PR - no internal issue.

If payment is not needed (e.g., regression PR review fix etc), react with 👎 to this comment to prevent the payment issue from being created.

@luacmartins luacmartins left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f640ba258

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/libs/actions/App.ts
@mountiny
mountiny merged commit 7e35c3d into Expensify:main Jun 29, 2026
39 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🚧 mountiny has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/mountiny in version: 9.4.22-1 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 cancelled 🔪
🍎 iOS 🍎 cancelled 🔪

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/mountiny in version: 9.4.24-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 failure ❌

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/cristipaval in version: 9.4.24-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 failure ❌

Bundle Size Analysis (Sentry):

@melvin-bot

melvin-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Payment issue created: #94954

@OSBotify

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/mountiny in version: 9.4.24-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 failure ❌

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants