Check your setup
Check: Run these checks to inspect the installation, platform, and configured models.
let primordial = PrimordialClient()
let integration = try primordial.integrationStatus()
let status = await primordial.ai.status()
print(integration.sdkVersion, integration.platform, integration.isSimulator)
print(status.generation, status.embedding, status.speech)
Fix: Find the matching problem below and follow its solution.
import Primordial fails
Check: Confirm that the app target links the Primordial product.
Fix: Remove duplicate package entries, choose File > Packages > Reset Package Caches, then add the package once using Getting Started.
The project compiles but AI execution fails
Check: Confirm these requirements:
- Xcode 26.0+ with the Swift 6.2+.
- iOS/iPadOS 17+ or macOS 14+.
- Physical iPhone/iPad or Apple silicon Mac for local AI.
- Appleās model requires OS 26+ and Apple Intelligence enabled on eligible hardware.
Fix: Run downloadable models, embeddings, and speech on a supported physical iOS device or Mac. Use the simulator only for installation and import checks.
Activation is required or rejected
Check: Print the activation error and confirm the credential and bundle identifier.
do {
try await primordial.activate(.evaluationKey("pk_eval_..."))
} catch let error as PrimordialActivationError {
print(error.localizedDescription)
}
Fix: Follow the matching error:
evaluationKeyInvalid,evaluationKeyRevoked, orevaluationKeyExpired: rotate or replace the key.unregisteredAppIdentifier: register the exact, case-sensitive bundle identifier.activationMetadataMissing: confirm the target has a bundle identifier and supported platform metadata.activationRequestFailed: check connectivity and try again without logging the key.
See Evaluation Keys for setup instructions.
A production license is missing or rejected
Check: Activate the bundled license and print the typed error.
do {
try await primordial.activate(.license(.bundled("Primordial.license")))
} catch let error as PrimordialActivationError {
print(error.localizedDescription)
}
Fix: Follow the matching error:
licenseMissing: addPrimordial.licenseto the app target and Copy Bundle Resources.licenseMalformed,licenseInvalidSignature,licenseUnknownKey, orlicenseUnsupportedVersion: download the current license again without editing it.licenseWrongAppIdentifier,licenseWrongPublisherId,licenseWrongPlatform, orlicenseWrongChannel: confirm the exact release identifier is registered and activate once while online.licenseExpired: connect the device and activate again. Contact Primordial support if renewal remains unavailable.productionLicenseRequired: replace the evaluation key with a production license in distributed builds.
Revoking a license in the console cannot remotely disable a copy already bundled in an offline app. That copy remains usable until its signed expiry and grace period end.
See Production Licenses for the complete setup.
A required capability is unavailable
Check: Inspect the workflow status and required storage.
let requirement = await primordial.ai.status(for: .answering)
print(requirement.downloadBytes)
print(requirement.requiredAvailableBytes)
Fix: Ask for download consent, then call makeAvailable for the required workflow.
for try await progress in primordial.ai.makeAvailable(.answering) {
print(progress.phase, progress.fractionCompleted ?? 0)
}
Installation fails storage or verification
Check: Inspect the reported error and available storage.
do {
for try await _ in primordial.ai.makeAvailable(.generation) { }
} catch PrimordialAIError.insufficientStorage(let requirement) {
print(requirement.requiredAvailableBytes)
print(requirement.availableBytes)
}
Fix: Follow the matching error:
downloadFailed: check connectivity and callmakeAvailableagain.verificationFailed: retry once; incomplete files are never marked installed.corruptedStorage: wait for active work to finish, remove the affected managed download through its matching advanced resource, then reinstall it.
try await primordial.advanced.generation.removeDownload()
for try await _ in primordial.ai.makeAvailable(.generation) { }
Use advanced.embedding or advanced.speech when those downloads are affected.
An installation was cancelled
Check: Confirm the task ended with CancellationError.
Fix: Ask for consent and call makeAvailable again. Primordial reuses completed downloads.
A model will not unload or residency failed
Check: Inspect its memory snapshot.
let value = await primordial.advanced.generation.residency()
print(value.state, value.isRetained, value.activeLeaseCount)
Fix: An active lease means work is still using the resource. A retained resource was
deliberately loaded; call unload() after that work finishes. For .failed, inspect
the public error and retry the intended load or unload operation. Backgrounding, Mac sleep, and memory
pressure may legitimately change an unleased resource to .unloaded.
Background downloads do not finalize on iOS
Check: Confirm that the main SwiftUI scene includes Primordial's background-download modifier.
WindowGroup {
ContentView()
}
.primordialBackgroundDownloads()
Fix: Add the modifier once. UIKit apps use the app delegate fallback shown in AI Model Setup. After a system relaunch, call the same
makeAvailable capability again. A user force-quit cancels the transfer.
Generation or structured output fails
Check: Match the error to the cause below.
Fix: Follow the matching error:
contextWindowExceeded: shorten the input, retrieved context, or conversation history and retry.invalidQuery: remove empty input and correct invalid limits, categories, fields, or weights.structuredOutputInvalid: try again or use a simpler schema.unsupportedFeature: inspectai.capabilities()and choose a workflow supported by the configured model.invalidConfiguration: use a positive response-token limit and a finite temperature from 0 through 1.generationFailed: retry when appropriate and discard partial output.
Thinking defaults: Local thinking is off when you omit generation options or use thinking: .automatic. Enable it for one local request with generationOptions: .init(thinking: .enabled). Apple Foundation Models supports per-request token and temperature options, but does not expose thinking-mode control; keep thinking: .automatic for Apple generation.
Collection indexing or search fails
Check: Confirm the data, query, and installed capabilities:
- Keep the
PrimordialClientidentifier stable for the same account or workspace. - Use nonempty collection names, record IDs, and fields; only text fields are embedded.
- Keep one value type per field name throughout a collection.
- Use nonempty queries, positive limits and field weights, and filters compatible with stored field types.
- Install
.semanticSearchbefore synchronization, reindexing, or text search.
Fix: Correct invalid data or queries. If the index is incompatible, rebuild it:
for try await progress in notes.reindex() {
print("Prepared:", progress.completedRecords, "/", progress.totalRecords)
print(progress.phase, progress.fractionCompleted)
}
A pause between progress updates can mean a large record is still being prepared. Use
.ready to identify completion; prepared records have not necessarily been saved yet.
See reindexing progress for the upcoming
per-record updates and Store & Search for collection requirements.
Collection synchronization fails
Check: Inspect the collection status and the typed error.
let status = try await notes.synchronizationStatus()
print(status.sourceIdentifier)
print(status.sourceSchemaVersion)
print(status.hasCheckpoint)
print(status.requiresSnapshot)
Fix: Follow the matching condition:
-
sourceMismatch: use the source identifier already bound to the collection, or callreset()before intentionally binding a different source. -
sourceSchemaMismatch: use.automaticor.snapshotto build a complete snapshot after a deliberate source schema change. -
checkpointRequired: run.automaticor.snapshotbefore requesting.incrementalsynchronization. -
checkpointExpiredorinvalidCheckpoint: run.automaticto fall back to a complete snapshot, or explicitly request.snapshot. -
invalidSynchronizationOptions: choose a batch size from1...1000. -
Cancellation: call
synchronize(from:)again. Completed checkpoints are reused and an incomplete replacement is not exposed to search.
for try await _ in notes.synchronize(
from: source,
options: .init(mode: .automatic)
) { }
reset() removes the collection's searchable records, checkpoint, and source binding. Use it
only when you intend to clear and rebind the collection.
SwiftData changes or removals are missing
Check: Confirm the SwiftData source requirements:
- The source uses the same
ModelContaineras the application data. - The encoded record ID is stable, nonempty, and unique.
- The fetch descriptor does not contain a predicate.
- The record ID preserves its value when the model is deleted.
Fix: Add .preserveValueOnDeletion to the stable record ID and synchronize again.
@Model
final class Note {
@Attribute(.unique, .preserveValueOnDeletion)
var id: UUID
var body: String
}
Filtered SwiftData sources are not supported. Map the complete model type into a collection, then use typed collection filters when searching.
See Synchronize SwiftData for the complete setup.
Recording or transcription fails
Check: Confirm the application target includes:
NSMicrophoneUsageDescriptionNSSpeechRecognitionUsageDescription- For a sandboxed macOS app, enable Audio Input under App Sandbox.
Fix: Add the missing permissions and enable Audio Input for sandboxed macOS apps. Install .voiceInput for file transcription and enhanced multilingual recording; microphone recording can otherwise use Apple speech recognition. After stop() or cancel(), create a new recording session. See Speech.