Skip to content

fix(desktop): prevent crash in Plan and Usage settings pane (#6506)#6590

Open
kodjima33 wants to merge 1 commit intomainfrom
fix/plan-usage-crash
Open

fix(desktop): prevent crash in Plan and Usage settings pane (#6506)#6590
kodjima33 wants to merge 1 commit intomainfrom
fix/plan-usage-crash

Conversation

@kodjima33
Copy link
Copy Markdown
Collaborator

Summary

Fixes #6506 — the app crashes immediately when navigating to Settings > Plan and Usage.

Root Cause

The crash occurs in SubscriptionPlanCatalogMerger.merge() during view body evaluation. The crash trace shows:

_NativeDictionary.merge assertion failure
→ SettingsContentView.mergePlanCatalog
→ mergedPlanCatalog.getter
→ currentPlanBillingDetail.getter
→ currentPlanSubtitle.getter

The dictionary merge crashes when processing plan/price data with empty or unexpected IDs from the API.

Changes

  • Filter empty IDs: Plans and prices with empty id fields are filtered out before merging, preventing dictionary key collisions
  • Pre-allocate dictionary capacity: Use Dictionary(minimumCapacity:) for better performance and to avoid rehashing during merge
  • Safe enum decoding: Added unknown cases to SubscriptionPlanType and SubscriptionStatusType with custom decoders that gracefully handle new/unknown values from the API instead of crashing
  • Early return for empty catalogs: Skip merge entirely when both sources are empty

Testing

  • Syntax validation passes
  • Changes are minimal and defensive — no behavior changes for valid data
  • Handles edge cases: empty IDs, unknown plan types, unknown statuses

- Filter out plans/prices with empty IDs before merging to prevent
  dictionary assertion failures in SubscriptionPlanCatalogMerger
- Add unknown cases to SubscriptionPlanType and SubscriptionStatusType
  enums with safe decoding fallbacks to prevent crashes when the API
  returns unexpected values
- Guard mergedPlanCatalog early return for empty catalogs

Crash trace: _NativeDictionary.merge assertion failure triggered via
SettingsContentView.mergePlanCatalog → mergedPlanCatalog →
currentPlanBillingDetail → currentPlanSubtitle during view body
evaluation on the main thread.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 13, 2026

Greptile Summary

This PR fixes a crash in the Plan and Usage settings pane by filtering empty IDs before dictionary merging, pre-allocating dictionary capacity, and adding .unknown fallback cases to SubscriptionPlanType and SubscriptionStatusType so unexpected API values no longer throw during Codable decoding.

  • Build-breaking: The currentPlanTitle switch in SettingsPage.swift covers only .basic, .unlimited, and .pro — Swift requires exhaustive switches, so the newly added .unknown case causes a compile error that will break the release pipeline.
  • Unrelated files: .cursor/rules/arc.md and .windsurf/workflows/arc.md are personal developer tooling configs (Korean-language Arc pipeline) that appear to have been committed accidentally.

Confidence Score: 3/5

Not safe to merge — introduces a compile error that will break the automated release pipeline.

The crash fix logic (empty-ID filtering, safe enum decoding, defensive merge guard) is correct, but adding case .unknown to SubscriptionPlanType without updating the currentPlanTitle switch makes the code non-exhaustive, which is a Swift compile error. The Codemagic release build will fail until a case .unknown: branch is added to that switch.

desktop/Desktop/Sources/MainWindow/Pages/SettingsPage.swift — the currentPlanTitle switch at line 5582 must handle .unknown before this can ship.

Important Files Changed

Filename Overview
desktop/Desktop/Sources/MainWindow/Pages/SettingsPage.swift Adds SubscriptionPlanCatalogMerger with empty-ID filtering and defensive mergedPlanCatalog computed property, but the currentPlanTitle switch is now non-exhaustive (missing case .unknown) — this is a compile error.
desktop/Desktop/Sources/APIClient.swift Adds .unknown fallback cases with custom decoders to SubscriptionPlanType and SubscriptionStatusType, correctly preventing Codable crashes for unknown API values.
.cursor/rules/arc.md New Korean-language Arc pipeline workflow config file; appears to be personal developer tooling unrelated to this bug fix.
.windsurf/workflows/arc.md Duplicate of .cursor/rules/arc.md for Windsurf; same unrelated personal tooling observation applies.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[loadSubscriptionInfo] --> B[getUserSubscription]
    A --> C[getAvailablePlans]
    B --> D[userSubscription set]
    C --> E[fallbackPlanCatalog = planCatalog from plans]
    D & E --> F[mergedPlanCatalog getter]
    F --> G{both empty?}
    G -- yes --> H[return empty array]
    G -- no --> I[filter empty IDs from primary & fallback]
    I --> J[SubscriptionPlanCatalogMerger.merge]
    J --> K[Build mergedById dict with minimumCapacity]
    K --> L[Insert fallback plans]
    L --> M[Insert/merge primary plans]
    M --> N[mergePrices for overlapping plan IDs]
    N --> O[return Array of merged plans]
    O --> P[subscriptionPlansForDisplay sorts result]
    P --> Q[currentPlanBillingDetail]
    P --> R[currentPlanTitle switch]
    R --> S[.basic / .unlimited / .pro]
    R -.->|missing case| T[.unknown - compile error]
    Q --> U[currentPlanSubtitle]
    U --> V[Plan & Usage UI renders]
Loading

Comments Outside Diff (1)

  1. desktop/Desktop/Sources/MainWindow/Pages/SettingsPage.swift, line 5582-5589 (link)

    P0 Non-exhaustive switch breaks compilation

    This switch now covers only basic, unlimited, and pro, but the PR just added a fourth case, .unknown, to SubscriptionPlanType. Swift requires exhaustive switches on enums; this will produce a compile error ("Switch must be exhaustive") and break the build.

Reviews (1): Last reviewed commit: "fix(desktop): prevent crash in Plan and ..." | Re-trigger Greptile

Comment on lines +1 to +5
---
description: arc 파이프라인 운영 (Evidence → Work → Projection → Output)
---

arc MCP가 연결되면 이 워크플로우가 자동으로 활성화됩니다.
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.

P2 Unrelated developer tooling files committed

Both .cursor/rules/arc.md and .windsurf/workflows/arc.md are Korean-language workflow configuration files for an "Arc" project-management pipeline tool. They are not related to the desktop crash fix, appear to be personal developer tooling, and likely should not be part of the repo history. Consider removing them from this PR and adding the paths to .gitignore.

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.

Desktop: Crash when accessing Plan and Usage settings pane.

1 participant