From sqlitedata-swift
Use when a SQLiteData error message or unexpected behavior occurs — symptom-to-fix lookup for build errors, runtime crashes, migration failures, and query problems. NOT for implementing features (use core) or learning CloudKit sync patterns (use router)
How this skill is triggered — by the user, by Claude, or both
Slash command
/sqlitedata-swift:sqd-diagThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Symptom-based troubleshooting for SQLiteData issues.
Symptom-based troubleshooting for SQLiteData issues.
import SQLiteData (it re-exports StructuredQueriesSQLite)swift-structured-queries dependency (should come transitively via SQLiteData)@Table struct fields match the SQL schema typesTEXT → String or UUID, INTEGER → Int or Bool, REAL → Double, BLOB → DataQueryBindable.select { } closure@Selection struct field types match query expressionsnonisolated before the struct: @Table nonisolated struct Item { ... }migrator.migrate(database) is called@Table("customName") must match SQL CREATE TABLE "customName"prepareDependencies not calledON DELETE CASCADENOT NULL ON CONFLICT REPLACE DEFAULT <value>DatabasePool instead of DatabaseQueuedatabase.write callsQuick symptom→fix map. For full CloudKit sync patterns, use /skill sqd-cloudkit.
| Symptom | Fix |
|---|---|
| SyncEngine init throws about UNIQUE | Remove all UNIQUE constraints from synced tables (except PK). Workaround: make the unique column the primary key via @Column(primaryKey: true) — see /skill sqd-cloudkit §3 |
| SyncEngine init throws about RESTRICT/NO ACTION | Change to ON DELETE CASCADE, SET NULL, or SET DEFAULT |
write-permission-error | User lacks write permission on shared record — catch via SyncEngine.writePermissionError |
invalid-record-name-error | Primary key has non-ASCII chars, >255 chars, or starts with underscore |
| Data not syncing | Check: isRunning == true, iCloud signed in, capabilities enabled, table listed in SyncEngine(tables:) |
| Records sync but data wrong | Missing NOT NULL ON CONFLICT REPLACE DEFAULT on non-nullable columns |
limitExceeded / batchRequestFailed | Transient — SyncEngine retries automatically |
| Share not working | Check: CKSharingSupported in Info.plist, table in tables: (not privateTables:), root record with UUID PK, acceptShare(metadata:) in SceneDelegate |
@Observable class: add @ObservationIgnored to the fetch property wrappers@Dependency(\.defaultDatabase) must be the prepared oneprepareDependencies only called once?prepareDependencies not called, or called after first accesslet _ = prepareDependencies { ... } at top of #Preview.dependency(\.defaultDatabase, ...) trait.where { } filter may be wrong@Table$property.loadError for details#sql(...) macroFetchKeyRequest requires a key value before it fetches — check the key is set@Fetch(ItemRequest()) with a default key, ensure the key matches an actual row@Fetch does not auto-load on init — call load() or set a key to trigger the fetch$property.loadError — a nil key produces no error but also no dataSharedReader caches the last emitted value — if the underlying query changes shape (e.g. table renamed), the reader stays stale@FetchAll uses ValueObservation internally — if the observed tables haven't changed, no update firesdb.execute(sql:)) bypass StructuredQueries change tracking — use @Table query builders insteadDatabaseQueue: only one connection, reads wait on writes — observation may appear delayedFetchSubscription.cancel() called too earlyDatabaseQueue in multithreaded context (use DatabasePool)#if DEBUG: migrator.eraseDatabaseOnSchemaChange = trueManuallyMigratingPrimaryKeys docs#Preview {
let _ = try! prepareDependencies {
try $0.bootstrapDatabase()
try? $0.defaultDatabase.seedSampleData()
}
ContentView()
}
SyncEngine init isn't hitting networkstartImmediately: false and don't call .start() in previewsdefaultDatabase().dependency(\.defaultDatabase, ...) trait per suitetry migrator.migrate(database)bootstrapDatabase() helperprepareDependencies calls — ensure both set up the same migrationsseedSampleData() which inserts rows — tests should start clean@MainActor isolation in tests can cause issues with database access — use nonisolated test methods or withDependencies for explicit setupNSHomeDirectory() changes per boot.completeUnlessOpen may not block reads as expectedimport SQLiteData present?prepareDependencies called once at app start?migrator.migrate(database) called?@ObservationIgnored on fetch property wrappers in @Observable?@Table and SQL?ON CONFLICT REPLACE?configuration.foreignKeysEnabled = true if using foreign keys?Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.
npx claudepluginhub sitapix/sqlitedata-swift-skills --plugin sqlitedata-swift