{"record":{"id":"3f5a2cf9addc1728","repo":"tursodatabase/turso","slug":"sync-is-disabled-as-database-was-opened-without-sy-3f5a2c","errorCode":null,"errorMessage":"sync is disabled as database was opened without sync support","messagePattern":"sync is disabled as database was opened without sync support","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/javascript/sync/packages/wasm/promise-bundle.ts","lineNumber":194,"sourceCode":"                    registerFileAtWorker(this.#worker, this.name),\n                    registerFileAtWorker(this.#worker, `${this.name}-wal`),\n                    registerFileAtWorker(this.#worker, `${this.name}-wal-revert`),\n                    registerFileAtWorker(this.#worker, `${this.name}-info`),\n                    registerFileAtWorker(this.#worker, `${this.name}-changes`),\n                ]);\n            }\n            await run(this.#runner, this.#engine.connect(), this.execLock);\n        }\n        this.connected = true;\n    }\n    /**\n     * pull new changes from the remote database\n     * if {@link DatabaseOpts.longPollTimeoutMs} is set - then server will hold the connection open until either new changes will appear in the database or timeout occurs.\n     * @returns true if new changes were pulled from the remote\n     */\n    async pull() {\n        if (this.#engine == null) {\n            throw new Error(\"sync is disabled as database was opened without sync support\")\n        }\n        const changes = await this.#guards.wait(async () => await run(this.#runner, this.#engine.wait(), this.execLock));\n        if (changes.empty()) {\n            return false;\n        }\n        await this.#guards.apply(async () => await run(this.#runner, this.#engine.apply(changes), this.execLock));\n        return true;\n    }\n    /**\n     * push new local changes to the remote database\n     * if {@link DatabaseOpts.transform} is set - then provided callback will be called for every mutation before sending it to the remote\n     */\n    async push() {\n        if (this.#engine == null) {\n            throw new Error(\"sync is disabled as database was opened without sync support\")\n        }\n        await this.#guards.push(async () => await run(this.#runner, this.#engine.push(), this.execLock));\n    }","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/javascript/sync/packages/wasm/promise-bundle.ts#L176-L212","documentation":"pull() fetches new changes from the remote database, which requires a SyncEngine. When the Database is constructed without a url option the constructor takes the local-only branch (this.#engine = null), so pull() — like push(), checkpoint() and stats() — throws instead of silently doing nothing.","triggerScenarios":"new Database({ path: 'local.db' }) — DatabaseOpts.url omitted, or explicitly evaluated to undefined (e.g. url: process.env.TURSO_DATABASE_URL ?? undefined with the variable unset) — followed by await db.pull(). The guard is the first statement of pull(), so it fires before any engine work.","commonSituations":"Sharing one code path between a local-only dev/test database and a synced production database; CI or preview environments missing TURSO_DATABASE_URL so url evaluates to undefined; a refactor that accidentally drops the url field from DatabaseOpts; local (non-sync) WASM demo code later extended with a sync loop.","solutions":["Pass a url (and usually authToken) in DatabaseOpts: new Database({ path, url: process.env.TURSO_DATABASE_URL!, authToken }) — this is what creates the SyncEngine that pull/push/checkpoint/stats require.","If the database is intentionally local-only, remove the sync call or gate it behind a 'sync enabled' flag in your own code.","Verify the environment actually provides the URL in the failing context: log process.env.TURSO_DATABASE_URL at the exact construction site (CI/preview often differ from your machine).","Use two explicit factory functions — local Database for dev/tests, synced Database for prod — instead of conditionally omitting url on one shared path."],"exampleFix":"// before\nconst db = new Database({ path: \"app.db\" }); // no url -> constructor stores #engine = null\nawait db.pull();                               // throws \"sync is disabled...\"\n\n// after — opt into sync at construction time\nconst db = new Database({\n    path: \"app.db\",\n    url: process.env.TURSO_DATABASE_URL!, // required for pull/push/checkpoint/stats\n    authToken: process.env.TURSO_AUTH_TOKEN,\n});\nawait db.connect();\nawait db.pull();","handlingStrategy":"validation","validationCode":"// Decide once, where you build your options, whether sync is on.\nconst syncOpts = process.env.TURSO_DATABASE_URL\n    ? { url: process.env.TURSO_DATABASE_URL, authToken: process.env.TURSO_AUTH_TOKEN }\n    : {};\nconst db = new Database({ path: \"app.db\", ...syncOpts });\nconst syncEnabled = Boolean(syncOpts.url);\n\n// Guard every sync call site:\nif (syncEnabled) {\n    await db.connect();\n    await db.pull(); // likewise push(), checkpoint(), stats()\n}","typeGuard":"// #engine is private — there is no runtime probe on the Database instance.\n// Narrow your options instead, before construction:\nconst isSynced = (\n    opts: DatabaseOpts\n): opts is DatabaseOpts & { url: string | (() => string | null) } => opts.url != null;","tryCatchPattern":"try {\n    await db.pull();\n} catch (e) {\n    if (e instanceof Error && e.message.startsWith(\"sync is disabled\")) {\n        // Local-only database: this is a configuration state, not a transient error.\n        // Skip the sync loop (or alert that this deployment was meant to sync).\n        return;\n    }\n    throw e;\n}","preventionTips":["Treat url as the single switch for sync: never call pull/push/checkpoint/stats on a Database whose options did not include url.","Construct local (dev/test) and synced (prod) databases through separate explicit factories instead of conditionally omitting url on one shared path.","Fail fast at startup if a deployment is supposed to sync but TURSO_DATABASE_URL is missing.","Do not treat connect() succeeding as proof of sync support — connect() also works for local-only databases; only the sync methods throw."],"tags":["wasm","sync","local-mode","api-misuse","configuration"],"backgroundTag":"feature-not-enabled","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}