Skip to content

MBLoggerCoreDataManager: fatalError in FileManager.storeURL crashes the host app when App Group container is unavailable on iOS Simulator first-launch — should throw and let bootstrap() degrade gracefully #705

@eugene-lisovskiy

Description

@eugene-lisovskiy

Summary

When the host app's App Group entitlement is correctly configured but the container isn't yet mounted (clean iOS Simulator install after simctl uninstall / simctl install), FileManager.storeURL(for:databaseName:) calls fatalError which crashes the host process.

The bootstrap() method that ultimately consumes this URL is already wrapped in do/catch (MBLoggerCoreDataManager.swift:93-117) and would degrade storageState to .disabled if loadContainer threw — but fatalError short-circuits the catch and brings down the entire host app.

Reproduction

  1. Host app with valid group.cloud.Mindbox.<bundle-id> entitlement (verified embedded via codesign -d --entitlements - Runner.app).
  2. Cycle the install on iOS Simulator:
    xcrun simctl uninstall booted <bundle-id>
    xcrun simctl install booted Runner.app
    xcrun simctl launch booted <bundle-id>
  3. App crashes with EXC_BREAKPOINT (SIGTRAP).

Stack trace from the .ips report:

FileManager.storeURL(for:databaseName:)        — FileManager+Extensions.swift:13
  closure #1 in MBLoggerCoreDataManager.init   — MBLoggerCoreDataManager.swift:18-23
    MBLoggerCoreDataManager.bootstrap()        — line 93
  ← Mindbox.assembly()
    Mindbox.shared.unsafeMutableAddressor      — first access of the lazy singleton
      AppDelegate.initializeMindboxSdk()       — our host code calling Mindbox.shared.initialization(configuration:)

Reproduces 100% on Xcode 26.x / iOS 26.5 Simulator with Mindbox and MindboxLogger both at 2.15.0.

Why this matters

  • Blocks automated UI testing on iOS Simulator (Maestro / XCUITest with clearState: true / simctl uninstall between runs).
  • Affects every first-launch on a CI runner that wipes the simulator between builds.
  • Related to Thread 1: Fatal error: containerURL not found for group:  #124 (closed as a host misconfiguration) and Crash at MBLoggerCoreDataManager #585 (fixed a different fatalError in persistentContainer in 2.14.2). The pattern of using fatalError from within the SDK's init path is the deeper issue — an SDK should never bring down its host app just because one of its capabilities can't be initialized.

The host app's entitlement is correctly configured. The container is simply not yet available because the OS hasn't finished setting up the App Group sandbox on a brand-new install. Subsequent launches succeed (which is why this only shows up under automation, not under hand-driven QA).

Proposed fix

FileManager+Extensions.swift:

extension FileManager {
    enum StoreURLError: Error {
        case containerUnavailable(appGroup: String)
    }

    static func storeURL(for appGroup: String, databaseName: String) throws -> URL {
        guard let fileContainer = FileManager.default
            .containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
            throw StoreURLError.containerUnavailable(appGroup: appGroup)
        }
        return fileContainer.appendingPathComponent("\(databaseName).sqlite")
    }
}

Update callers (currently a single call site inside LoggerDatabaseLoader) to propagate the throws. MBLoggerCoreDataManager.bootstrap() already has a catch branch that sets storageState = .disabled and logs the failure — the new throw lands there cleanly. No behavior change in the happy path.

This keeps the original semantic guidance for misconfigured hosts (the host's logging is silently disabled and the developer sees an [MBLoggerCDManager] bootstrap failed: containerUnavailable(appGroup: ...) line in the console) while removing the crash.

If you want a louder signal for misconfigured hosts in DEBUG, an assertionFailure instead of fatalError would also keep the bootstrap path crash-free in release builds while still flagging the issue during development.

Environment

  • Mindbox 2.15.0
  • MindboxLogger 2.15.0
  • MindboxNotifications 2.15.0
  • mindbox_ios (Flutter plugin) 2.15.0
  • Xcode 26.x / iOS 26.5 Simulator (iPhone 17 Pro)
  • Host: Flutter 3.x app, native AppDelegate.swift calling Mindbox.shared.initialization(configuration:) from didFinishLaunchingWithOptions before GeneratedPluginRegistrant.register(with: self)
  • App Group: group.cloud.Mindbox.<bundle-id> (verified embedded in the .app's entitlements)

Happy to provide the full .ips crash log on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions