You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-09-09] [$250] [Sentry: APP-EF1] HybridApp iOS App Hang in MarkdownTextInput Yoga layout (createStringFromUtf8) #93831
The local evidence matches this recurring failure shape: native callback assumes current policy/report still exists. Here, src/libs/HybridApp.ts:118 and src/libs/HybridApp.ts:95 do not agree on the same APP, EF1, HybridApp value, so the user-visible path can show a missing or stale state even though nearby data already has the needed context.
What changes do you think we should make in order to solve the problem?
Update src/libs/HybridApp.ts:118 to derive APP, EF1, HybridApp from the matched app state path that owns this flow before the value is consumed.
Carry the same normalized value through src/libs/HybridApp.ts:95; that follows the safer family move to add the guard at the ownership boundary, not only at render, so the write/optimistic/read paths agree instead of only changing the visible component.
Keep the change inside the Sentry Crash, Null/Undefined, Native Hybrid surface and avoid changing do not hide crashes with blanket catch, native platform differences.
What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?
Add or update a regression in tests/unit/**/*.ts for the exact issue flow: [$250] [Sentry: APP-EF1] HybridApp iOS App Hang in MarkdownTextInput Yoga layout (createStringFromUtf8).
Cover the counter-case near src/libs/HybridApp.ts:118 so valid existing APP, EF1, HybridApp behavior still works.
Manually repeat the issue steps after the patch and confirm the visible state/action is no longer stale.
What alternative solutions did you explore? (Optional)
I would not add a broad new condition outside these referenced paths; the safer fix is to keep APP, EF1, HybridApp consistent at the first read/write boundary shown above.
Root Cause (high confidence): This App Hang is not in the App repo — it's in the @expensify/react-native-live-markdown@0.1.327 native iOS code. On every Yoga layout/measure pass, the markdown decorator synchronously re-parses the entire input text on the main thread via JSI. For a large composer value (e.g. a big paste), that parse exceeds iOS's ~2s watchdog and the OS kills the app as an AppHang.
The reported stack maps line-for-line to the library:
measureContent calls applyMarkdownFormattingToTextInputState unconditionally on each measure pass (...ShadowNode.mm:126) — Yoga can call this many times per layout.
A freshRCTMarkdownUtils / MarkdownParser / MarkdownFormatter is allocated and the full string re-parsed every time, with no caching keyed on the unchanged text (...ShadowNode.mm:186-189, RCTMarkdownUtils.mm:29). The author even flagged this: // this can possibly be optimized.
MarkdownParser parse runs a JSI/Hermes-backed parser (hence createStringFromUtf8), so the cost grows with text length and runs on the main thread during layout.
⚠️This fix is outside the App repo. The root cause lives in Expensify/react-native-live-markdown (a separate package), so I can't propose an App-side code change here. The existing proposal above pointing at src/libs/HybridApp.ts is unrelated — that file has nothing to do with the markdown measure path. This should be escalated to an engineer who can work in the live-markdown repo.
Recommended fix (in react-native-live-markdown):
Cache the parse result keyed on {string, parserId, markdownStyle} so an unchanged text isn't re-parsed on every measure pass / Yoga measure call.
Skip re-applying markdown in measureContent when the attributed string content hasn't changed since the last formatting pass.
Once a fixed version is published, bump @expensify/react-native-live-markdown in App/package.json (currently 0.1.327).
Investigation details & alternatives considered
Trigger (unconfirmed): The crash mechanism is confirmed from code+stack, but the specific input that pushes a single parse past 2s isn't proven from logs. Most likely a large text value in a markdown-enabled input (composer / big paste). A log-investigator / Sentry breadcrumb pass on APP-EF1 events could confirm the route and approximate text size, but isn't required to identify the root cause.
Sibling APP-EG9 (createStringFromUtf8 hang) is almost certainly the same library, different entry point — fixing the parse caching here should address both.
Alternative explanation considered: a genuine infinite/retain loop in measure. Ruled out — the frames show a single linear parse→format chain, not recursion; the hang scales with text size, consistent with O(n) parsing on the main thread, not a loop.
Why not fix in App: App only consumes MarkdownTextInput from the library; the measure callback, parser allocation, and lack of caching are all inside the package's native code. There is no App-level hook to make this parse async or cached.
Next Steps: This requires a change in Expensify/react-native-live-markdown, not App — please escalate to an engineer with access to that repo. Reply with @MelvinBot <feedback> to refine this analysis.
The stack trace is correct about where the time is spent, but the conclusion that this is "outside the App repo / not fixable in App" is wrong. The parser that the native measure path executes is our own worklet, registered from App code, so the hang is fully addressable here.
Walking the chain:
On every Yoga measure pass, the library re-applies markdown synchronously inside measureContent:
That allocates a fresh parser and re-parses the entire string with no caching keyed on unchanged text — the author even flagged // this can possibly be optimized (...ShadowNode.mm#L164-L189).
[_markdownParser parse:withParserId:] (RCTMarkdownUtils.mm#L29) does not run any built-in C++ parser — it dispatches into the JS worklet that was registered for parserId, hence the createStringFromUtf8 / Hermes frames.
That registered worklet is App code: RNMarkdownTextInput.tsx#L58-L69 builds parserWorklet, which (for the composer, where no parser prop is passed) defaults to parseExpensiMarkWithShortMentions → ParsingUtils.ts#L57-L62, i.e. a full ExpensiMark replace() tokenization of the whole input.
Why it hangs: Yoga calls the measure callback multiple times per layout pass, and the decorator re-runs the full parse on each call with no memoization of the unchanged string. On iOS HybridApp the initial/synchronous layout of a composer pre-filled with a sizeable draft runs on the main thread, so N × (single ExpensiMark parse) stacks up past iOS's ~2s watchdog → AppHang. The cost is multiplicative in the number of measure calls, not a single O(n) parse — which is exactly why moderate inputs (well under the library's 4000-char cut-off at parseExpensiMark.ts#L242) still hang.
So: native measureContent fires the App's parserWorklet many times per layout → each call re-parses the full string with no caching → on a main-thread layout the accumulated parse time trips the watchdog → AppHang (createStringFromUtf8).
Note the existing App "optimization" does not help here: the comment at RNMarkdownTextInput.tsx#L98-L101 claims maxLength "avoid[s] parsing markdown for large text", but maxLength only caps typed length (defaulted to CONST.MAX_COMMENT_LENGTH + 1 = 15001) — it never short-circuits the measure-time parse.
What changes do you think we should make in order to solve the problem?
Collapse the repeated parses into one by memoizing parserWorklet on its input string, inside the worklet that is already registered — no library change, no native code.
parserWorklet already closes over a Reanimated shared value (mentionsSharedVal, via useSharedValue already imported at RNMarkdownTextInput.tsx#L6 and used at #L34). Add a second useSharedValue cache holding the last {text, ranges} and have the worklet return the cached ranges when text is unchanged:
Because the worklet runs on the live-markdown runtime, the shared-value read/write is synchronous and coherent across the burst of measure calls in a single layout pass, so the N parses per layout collapse to 1 per unique string — directly removing the multiplier that causes the watchdog timeout. This is the same "cache the parse result keyed on the (unchanged) text" idea noted as the upstream fix, but done at the layer the App already owns.
I'd also fold the stale maxLength "optimization" comment into a real guard: short-circuit parserWorklet to [] for very long inputs (reusing the exact early-return pattern already at parseExpensiMark.ts#L242) so a single oversized parse can never run on the main thread either.
Minor changes/improvements (cache key including parserId/mentions, exact threshold) can be discussed in the PR phase.
What alternative solutions did you explore? (Optional)
Bump @expensify/react-native-live-markdown once caching is added natively in measureContent. That is the more permanent home for this, but it requires a coordinated library release + upgrade and still re-parses redundantly until then; the worklet-level memoization above is App-only, ships immediately, and fixes both this issue and the sibling createStringFromUtf8 hang (APP-EG9) since they share the same registered worklet.
App routes markdown-enabled inputs through RNMarkdownTextInput, including the composer and BaseTextInput type="markdown" call sites. That wrapper passes the native package parser and defaults its native maxLength to CONST.MAX_COMMENT_LENGTH + 1, while CONST.MAX_COMMENT_LENGTH is 15,000.
What changes do you think we should make in order to solve the problem?
Patch @expensify/react-native-live-markdown on iOS so MarkdownParser.parse() applies the same parsable-length budget natively before jsi::String::createFromUtf8(). For over-budget input, return the empty ranges immediately (or cache only the over-budget decision without retaining the full string) so Yoga can measure plain text without entering JSI or the worklet parser.
Stop losing the native parser cache on every layout pass. Either keep a reusable RCTMarkdownUtils/MarkdownParser for the decorator shadow node, or add a package-level native range cache keyed by text + parser id. The style/default attributes can still be applied after the cached ranges are returned, so markdown rendering for normal composer text is unchanged.
Consume the package fix in App by either bumping @expensify/react-native-live-markdown and the iOS pod lock, or by adding a temporary App patch-package entry plus patches/.../details.md if a package release is not ready. Add an iOS regression fixture around MarkdownParser/RCTMarkdownUtils proving a string longer than 4,000 characters returns empty ranges before the worklet/JSI parse path is invoked.
Scope boundaries: files touched should be limited to the live-markdown iOS parser/utility/shadow-node code and the App dependency/patch metadata (package.json, package-lock.json, ios/Podfile.lock, and/or patches/@expensify/react-native-live-markdown). Platforms affected: iOS native / HybridApp markdown TextInputs only. Code paths not touched: backend APIs, comment length validation, Android/web markdown rendering, and normal <=4,000-character markdown highlighting.
What alternative solutions did you explore? (Optional)
Lowering RNMarkdownTextInput's maxLength or CONST.MAX_COMMENT_LENGTH would change valid comment/task/description limits and still would not protect controlled/default native values that are already mounted. Disabling live markdown on HybridApp would avoid the hang but regresses all markdown-enabled inputs. Moving all markdown formatting out of measurement is broader and risks incorrect initial auto-grow sizing; the native length guard plus persistent parser cache targets the exact Sentry stack with less behavior change.
⚠️@KJ21-ENG Thanks for your proposal. Please update it to follow the proposal template, as proposals are only reviewed if they follow that format (note the mandatory sections).
[Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
Link to the comment on the PR:
Link to the comment on the Issue:
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
Regression Test Proposal
Not reliably reproducible crash reported by Sentry so we can skip regression test
Activity
melvin-bot commentedon Jun 17, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @abzokhattab (
External)melvin-bot commentedon Jun 17, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022067265891842535098
godzillaxbox19982014-lgtm commentedon Jun 17, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
[$250] [Sentry: APP-EF1] HybridApp iOS App Hang in MarkdownTextInput Yoga layout (createStringFromUtf8)
What is the root cause of that problem?
I traced this to the path that handles
APP, EF1, HybridApp:closeReactNativeApp):closeReactNativeApp({shouldSetNVP: false, isTrackingGPS: false});if):if (!credentials?.autoGeneratedLogin || !credentials?.autoGeneratedPassword || account?.requiresTwoFactorAuth === undefined || account?.needsTwoFactorAuthSetup === undefined) {if):if (tryNewDot !== undefined) {src/libs/HybridApp.ts:118andsrc/libs/HybridApp.ts:95do not agree on the sameAPP, EF1, HybridAppvalue, so the user-visible path can show a missing or stale state even though nearby data already has the needed context.What changes do you think we should make in order to solve the problem?
src/libs/HybridApp.ts:118to deriveAPP, EF1, HybridAppfrom the matched app state path that owns this flow before the value is consumed.src/libs/HybridApp.ts:95; that follows the safer family move to add the guard at the ownership boundary, not only at render, so the write/optimistic/read paths agree instead of only changing the visible component.What specific scenarios should we cover in automated tests to prevent reintroducing this issue in the future?
tests/unit/**/*.tsfor the exact issue flow: [$250] [Sentry: APP-EF1] HybridApp iOS App Hang in MarkdownTextInput Yoga layout (createStringFromUtf8).src/libs/HybridApp.ts:118so valid existingAPP, EF1, HybridAppbehavior still works.What alternative solutions did you explore? (Optional)
APP, EF1, HybridAppconsistent at the first read/write boundary shown above.MelvinBot commentedon Jun 17, 2026
Issue Analysis
Root Cause (high confidence): This App Hang is not in the App repo — it's in the
@expensify/react-native-live-markdown@0.1.327native iOS code. On every Yoga layout/measure pass, the markdown decorator synchronously re-parses the entire input text on the main thread via JSI. For a large composer value (e.g. a big paste), that parse exceeds iOS's ~2s watchdog and the OS kills the app as an AppHang.The reported stack maps line-for-line to the library:
yogaNodeMeasureCallbackConnectorMarkdownTextInputDecoratorShadowNode.mm:256-299measureContentMarkdownTextInputDecoratorShadowNode.mm:110-131applyMarkdownFormattingToTextInputStateMarkdownTextInputDecoratorShadowNode.mm:164-253RCTMarkdownUtils applyMarkdownFormatting→MarkdownParser parse→createStringFromUtf8RCTMarkdownUtils.mm:20-35Two things make it expensive on every measure:
measureContentcallsapplyMarkdownFormattingToTextInputStateunconditionally on each measure pass (...ShadowNode.mm:126) — Yoga can call this many times per layout.RCTMarkdownUtils/MarkdownParser/MarkdownFormatteris allocated and the full string re-parsed every time, with no caching keyed on the unchanged text (...ShadowNode.mm:186-189,RCTMarkdownUtils.mm:29). The author even flagged this:// this can possibly be optimized.MarkdownParser parseruns a JSI/Hermes-backed parser (hencecreateStringFromUtf8), so the cost grows with text length and runs on the main thread during layout.Recommended fix (in
react-native-live-markdown):{string, parserId, markdownStyle}so an unchanged text isn't re-parsed on every measure pass / Yoga measure call.measureContentwhen the attributed string content hasn't changed since the last formatting pass.@expensify/react-native-live-markdowninApp/package.json(currently0.1.327).Investigation details & alternatives considered
log-investigator/ Sentry breadcrumb pass on APP-EF1 events could confirm the route and approximate text size, but isn't required to identify the root cause.createStringFromUtf8hang) is almost certainly the same library, different entry point — fixing the parse caching here should address both.MarkdownTextInputfrom the library; the measure callback, parser allocation, and lack of caching are all inside the package's native code. There is no App-level hook to make this parse async or cached.Next Steps: This requires a change in
Expensify/react-native-live-markdown, not App — please escalate to an engineer with access to that repo. Reply with@MelvinBot <feedback>to refine this analysis.yusufdeveloper2903 commentedon Jun 17, 2026
Proposal
What is the root cause of that problem?
The stack trace is correct about where the time is spent, but the conclusion that this is "outside the App repo / not fixable in App" is wrong. The parser that the native measure path executes is our own worklet, registered from App code, so the hang is fully addressable here.
Walking the chain:
On every Yoga measure pass, the library re-applies markdown synchronously inside
measureContent:MarkdownTextInputDecoratorShadowNode.mm#L110-L131callsapplyMarkdownFormattingToTextInputStateunconditionally atL126.// this can possibly be optimized(...ShadowNode.mm#L164-L189).[_markdownParser parse:withParserId:](RCTMarkdownUtils.mm#L29) does not run any built-in C++ parser — it dispatches into the JS worklet that was registered forparserId, hence thecreateStringFromUtf8/ Hermes frames.That registered worklet is App code:
RNMarkdownTextInput.tsx#L58-L69buildsparserWorklet, which (for the composer, where noparserprop is passed) defaults toparseExpensiMarkWithShortMentions→ParsingUtils.ts#L57-L62, i.e. a full ExpensiMarkreplace()tokenization of the whole input.Why it hangs: Yoga calls the measure callback multiple times per layout pass, and the decorator re-runs the full parse on each call with no memoization of the unchanged string. On iOS HybridApp the initial/synchronous layout of a composer pre-filled with a sizeable draft runs on the main thread, so
N × (single ExpensiMark parse)stacks up past iOS's ~2s watchdog → AppHang. The cost is multiplicative in the number of measure calls, not a single O(n) parse — which is exactly why moderate inputs (well under the library's 4000-char cut-off atparseExpensiMark.ts#L242) still hang.So: native
measureContentfires the App'sparserWorkletmany times per layout → each call re-parses the full string with no caching → on a main-thread layout the accumulated parse time trips the watchdog → AppHang (createStringFromUtf8).Note the existing App "optimization" does not help here: the comment at
RNMarkdownTextInput.tsx#L98-L101claimsmaxLength"avoid[s] parsing markdown for large text", butmaxLengthonly caps typed length (defaulted toCONST.MAX_COMMENT_LENGTH + 1= 15001) — it never short-circuits the measure-time parse.What changes do you think we should make in order to solve the problem?
Collapse the repeated parses into one by memoizing
parserWorkleton its input string, inside the worklet that is already registered — no library change, no native code.parserWorkletalready closes over a Reanimated shared value (mentionsSharedVal, viauseSharedValuealready imported atRNMarkdownTextInput.tsx#L6and used at#L34). Add a seconduseSharedValuecache holding the last{text, ranges}and have the worklet return the cached ranges whentextis unchanged:Because the worklet runs on the live-markdown runtime, the shared-value read/write is synchronous and coherent across the burst of measure calls in a single layout pass, so the
Nparses per layout collapse to1per unique string — directly removing the multiplier that causes the watchdog timeout. This is the same "cache the parse result keyed on the (unchanged) text" idea noted as the upstream fix, but done at the layer the App already owns.I'd also fold the stale
maxLength"optimization" comment into a real guard: short-circuitparserWorkletto[]for very long inputs (reusing the exact early-return pattern already atparseExpensiMark.ts#L242) so a single oversized parse can never run on the main thread either.Minor changes/improvements (cache key including
parserId/mentions, exact threshold) can be discussed in the PR phase.What alternative solutions did you explore? (Optional)
Bump
@expensify/react-native-live-markdownonce caching is added natively inmeasureContent. That is the more permanent home for this, but it requires a coordinated library release + upgrade and still re-parses redundantly until then; the worklet-level memoization above is App-only, ships immediately, and fixes both this issue and the siblingcreateStringFromUtf8hang (APP-EG9) since they share the same registered worklet.KJ21-ENG commentedon Jun 17, 2026
🚨 Edited by proposal-police: This proposal was edited at 2026-06-17 15:59:31 UTC.
Proposal
What is the root cause of that problem?
The Sentry stack is in the iOS implementation of
@expensify/react-native-live-markdown, which App ships as0.1.327/RNLiveMarkdown 0.1.327:App/package.json
Lines 94 to 98 in 6ea10e7
App/ios/Podfile.lock
Lines 3703 to 3706 in 6ea10e7
App routes markdown-enabled inputs through
RNMarkdownTextInput, including the composer andBaseTextInput type="markdown"call sites. That wrapper passes the native package parser and defaults its nativemaxLengthtoCONST.MAX_COMMENT_LENGTH + 1, whileCONST.MAX_COMMENT_LENGTHis 15,000.App/src/components/RNMarkdownTextInput.tsx
Lines 87 to 102 in 6ea10e7
App/src/components/Composer/implementation/index.native.tsx
Lines 123 to 142 in 6ea10e7
App/src/components/TextInput/BaseTextInput/implementations.ts
Lines 8 to 12 in 6ea10e7
App/src/CONST/index.ts
Lines 5090 to 5094 in 6ea10e7
On iOS, the package replaces the child TextInput's Yoga measure callback, and each
measureContent()call applies markdown before returning the measured size. Inside that measure path it allocates a newRCTMarkdownUtils/MarkdownParser, soMarkdownParser's one-entry_prevTextcache is discarded across repeated Yoga measurements.MarkdownParser.parse()then creates a JSI string from the whole native string before the JS parser'sMAX_PARSABLE_LENGTH = 4000guard can return an empty range list. That is why a long or repeatedly measured markdown input can block the iOS layout pass atcreateStringFromUtf8, matching the reported stack.https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/apple/MarkdownTextInputDecoratorShadowNode.mm#L65-L93
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/apple/MarkdownTextInputDecoratorShadowNode.mm#L110-L127
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/apple/MarkdownTextInputDecoratorShadowNode.mm#L185-L190
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/apple/MarkdownTextInputDecoratorShadowNode.mm#L229-L231
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/apple/RCTMarkdownUtils.mm#L10-L15
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/apple/MarkdownParser.mm#L14-L32
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/src/parseExpensiMark.ts#L26-L27
https://github.com/Expensify/react-native-live-markdown/blob/c54eb86e18a5b14d0839e47b4b9665c1ed570aad/src/parseExpensiMark.ts#L241-L244
What changes do you think we should make in order to solve the problem?
@expensify/react-native-live-markdownon iOS soMarkdownParser.parse()applies the same parsable-length budget natively beforejsi::String::createFromUtf8(). For over-budget input, return the empty ranges immediately (or cache only the over-budget decision without retaining the full string) so Yoga can measure plain text without entering JSI or the worklet parser.RCTMarkdownUtils/MarkdownParserfor the decorator shadow node, or add a package-level native range cache keyed by text + parser id. The style/default attributes can still be applied after the cached ranges are returned, so markdown rendering for normal composer text is unchanged.@expensify/react-native-live-markdownand the iOS pod lock, or by adding a temporary App patch-package entry pluspatches/.../details.mdif a package release is not ready. Add an iOS regression fixture aroundMarkdownParser/RCTMarkdownUtilsproving a string longer than 4,000 characters returns empty ranges before the worklet/JSI parse path is invoked.Scope boundaries: files touched should be limited to the live-markdown iOS parser/utility/shadow-node code and the App dependency/patch metadata (
package.json,package-lock.json,ios/Podfile.lock, and/orpatches/@expensify/react-native-live-markdown). Platforms affected: iOS native / HybridApp markdown TextInputs only. Code paths not touched: backend APIs, comment length validation, Android/web markdown rendering, and normal <=4,000-character markdown highlighting.What alternative solutions did you explore? (Optional)
Lowering
RNMarkdownTextInput'smaxLengthorCONST.MAX_COMMENT_LENGTHwould change valid comment/task/description limits and still would not protect controlled/default native values that are already mounted. Disabling live markdown on HybridApp would avoid the hang but regresses all markdown-enabled inputs. Moving all markdown formatting out of measurement is broader and risks incorrect initial auto-grow sizing; the native length guard plus persistent parser cache targets the exact Sentry stack with less behavior change.github-actions commentedon Jun 17, 2026
93 remaining items
situchan commentedon Sep 3, 2026
Contributor+ Checklist:
[Contributor] The offending PR and associated issue have been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
Link to the comment on the PR:
Link to the comment on the Issue:
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
Regression Test Proposal
Not reliably reproducible crash reported by Sentry so we can skip regression test
melvin-bot commentedon Sep 5, 2026
@abzokhattab Whoops! This issue is 2 days overdue. Let's get this updated quick!
melvin-bot commentedon Sep 7, 2026
@abzokhattab Eep! 4 days overdue now. Issues have feelings too...
melvin-bot commentedon Sep 9, 2026
@abzokhattab Still overdue 6 days?! Let's take care of this!
abzokhattab commentedon Sep 11, 2026
@situchan can you please check if the issue no longer occurring so that Matt can process the payment and close the issue
situchan commentedon Sep 11, 2026
The fix landed on 9.4.65-3.
Looks like no longer happening after 9.4.64 so I think we're good to handle payment and close.
cc: @mallenexpensify
melvin-bot commentedon Sep 14, 2026
@situchan Whoops! This issue is 2 days overdue. Let's get this updated quick!
mallenexpensify commentedon Sep 15, 2026
Payment Summary
Contributor: @abzokhattab due $250 via NewDot
Contributor+: @situchan due $250 via NewDot
I think/hope that's correct.
laurenreidexpensify commentedon Sep 28, 2026
Approved $250 @situchan New Expensify