Cupertino Foundation Models

Failures, fixes and recovery

This ledger separates user-reported symptoms, confirmed native crash evidence, source findings and validation limits. It consolidates the available project history and the August 12 / September 1, 2026 support sessions. It is not a claim that every past conversation or every possible crash was recovered.

Historical reports from the example

Symptom and evidence Cause / mitigation in the current source Recovery and remaining limit
July 3: first streamed reply left the chat locked The generation event channel did not close. Current generation transport uses request-scoped callbacks and closes on terminal results. Handle both completion and stream errors; always clear sending state.
August 12: sending a message crashed in Hybrid and Offline Diagnostic collection read PCC supportedLanguages; repeated EXC_BAD_ACCESS, SIGSEGV and SIGBUS were traced to Apple runtime getters. Availability checks alone did not prevent it. Keep PCC language/capability getters disabled. Local requests must not probe those getters.
August 12: images crashed repeatedly after text started working Separate reports reached Attachment(imageURL:), attachment labeling and conversion into Prompt, terminating before Swift could throw. Native image ABI remains disabled. Vision supplies OCR/classification/barcode text; it is not general vision inference.
August 12: selected documents produced confusing errors Unsupported Office/binary inputs, file extraction and route-exhaustion errors were conflated. Use validated UTF-8/text PDF; unsupported input returns an actionable typed error. The hybrid router is removed in 0.3.0.
August 12: transcription sometimes crashed or took too long Audio format assertions, asynchronous start/cancel races and locale/asset preparation were investigated; no single cause was established for every slow request. Validate microphone formats, prefer SpeechAnalyzer, await cleanup, inspect engine/assets. First-use asset downloads can still be slow.
September 1: cloud selection immediately crashed; transcription backend was unclear PCC construction without configured host opt-in was unsafe in the beta path. Model choice and Speech mode were conflated in the example. PCC stays opt-in and requires Apple’s signing entitlement. Model and Speech selectors are separate; Speech server is not PCC.
September 1: cancellation-related Runner SIGTRAP A stored report preceded the successful physical matrix and terminated inside Foundation Models cancellation code. Keep session reservation until native work terminates. Later beta-8 checks passed; this does not establish beta-27.2 runtime safety.
September 1: required tools repeated calls Apple’s required-tool mode lacked an application exit budget. Bound calls with maximumToolCalls; a budget breach is a request failure, not a successful answer.
September 1: simultaneous streams and rapid reuse could interfere Shared listeners, late task cleanup and incomplete cancellation could affect another request. Per-request stream IDs, tokenized tracking and single-flight session lifecycle.

The historical September 1 physical matrix reported 15 passing executable checks on iOS 27 beta 8. PCC generation, native image attachment ABI, long-duration stress and all manual UI flows were not covered. That report is preserved in the historical audit, and is not reused as proof for the changed code or iOS 27.2.

Source findings fixed in the 0.3.0 iteration

Finding Correction
A second facade replaced the first facade’s MethodChannel receiver Default facades share one transport and its session/request registry.
Explicit PCC bypassed CloudPolicy.never; automatic plus whenExplicit could select PCC Cloud policy is checked before constructing PCC; automatic cloud selection requires automaticWithUserConsent.
Per-request cloud policy was serialized but ignored Null inherits session selection; never rejects an existing PCC session.
localeIdentifier preflight was ignored by availability Local availability and optional session preflight now validate the requested locale.
Repeated cancellation could clear a session’s cancellation reservation early Native callers share the cancellation task; Dart disposal/cancellation also share their pending futures.
Microphone cancellation returned before asynchronous startup/cleanup finished Cleanup retains startup and is explicitly awaited; a second live capture is rejected.
Missing host Speech/microphone usage strings could reach privacy APIs Native preflight rejects missing/empty keys before requesting access.
Unknown schemas became strings; missing array items were invented Unsupported shapes/constraints and invalid required/enum declarations are rejected.
Generation arguments relied partly on debug-only assertions Serialization validates ranges in release code, alongside native validation.
Late tool callbacks, malformed arguments and oversized output were unsafe Skip callbacks already completed/cancelled, reject non-object JSON and report oversized output instead of truncating it.
iOS 26 failures depended on localized message matching Known legacy generation errors now map through typed cases.
Empty text and failed image preprocessing could look like usable content Empty text is rejected and Vision errors propagate.

These are source corrections. See the September 19 validation record for checks actually executed. No new runtime coverage is implied by this table.

Guided streaming in 0.3.1

If a text stream fails JSON parsing at the first character, asking for JSON in the prompt did not constrain native generation. Use streamStructured or pass schema to stream. Replace cumulative snapshots; do not concatenate them or save them as completed data. Read CompletionEvent.response.structuredValue. The new route rejects malformed schemas and incomplete/undecodable final content. This release was reviewed in source; no new build or device result is claimed. See guided streaming.

Reliability contracts in 0.4.0

Read migration before upgrading. Missing usage counters are nullable. Use measureTokenBudget to identify which local components were counted; PCC counts are unavailable, and overlapping components must not be added as an exact request total. A normal completion has an unknown stop reason unless Apple reports one. Neither estimates nor token usage prove truncation.

For timeouts inspect exception.termination.timeoutPhase (first response, idle or total), then await cleanup before reuse. A close without a terminal result is an error. Recreate sessions whose cancellation could not be confirmed. Schema mapper failures include details['schemaPath'].

For reproducible partial-output failures use the explicit, bounded diagnostic callback. It saves/uploads nothing; the host owns any captured data. OS suspension, entitled PCC generation and long-document completeness still require physical integration evidence.

Recover by error code

  • appleIntelligenceDisabled, assetsUnavailable: check Apple Intelligence, supported device/Siri languages and completed model downloads. Recheck when settings change; do not loop requests while assets are missing.
  • unsupportedPlatform, unsupportedOsVersion, unsupportedCapability: disable the unsupported feature or select an explicitly supported configuration.
  • unsupportedLanguage: select a supported locale; changing instructions alone cannot add language support.
  • missingEntitlement: obtain and sign with Apple’s managed PCC entitlement, then enable the host plist flag. The flag alone does not grant access; this status can also mean the package opt-in is off. Follow the request and signing steps.
  • invalidRequest: fix conflicting policy, schema, options, file format or missing host usage descriptions. Retry only after changing the cause.
  • parsingFailure: discard the partial structured result. Preserve the input, simplify or bound the request and inspect whether generation was incomplete. Do not repair arbitrary text into a successful financial/business result.
  • contextSizeExceeded: split input or create a new session; account for instructions, schema, tools, history and output, not only the user prompt.
  • concurrentRequests: wait for request/cancellation cleanup; do not force reuse.
  • guardrailViolation, refusal: provide an appropriate alternative; do not automatically send the same request to another provider.
  • generationTimeout, transcriptionTimeout, cancelled: clear loading state, await cleanup and reconcile tool side effects before retrying.
  • speechRecognitionDenied: request permissions at the point of use; offer Settings/manual input after denial.
  • speechRecognitionUnavailable: inspect locale, assets and microphone/audio availability. A server fallback needs an app policy that permits it.
  • quotaExceeded, networkUnavailable, privateCloudServiceUnavailable: report the PCC state; use a separately chosen local task if suitable.

If a process terminates, collect the .ips stack, OS build, Xcode/SDK build, package version, selected mode, operation and reproduction steps. Remove user prompts, transcripts, credentials, file contents and device identifiers before sharing a report. A native abort cannot be recovered by a Dart try/catch.