{"record":{"id":"3279e088bf995343","repo":"tursodatabase/turso","slug":"sync-is-disabled-as-database-was-opened-without-sy-3279e0","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":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bindings/javascript/sync/packages/wasm/promise-default.ts","lineNumber":189,"sourceCode":"            await super.connect();\n        } else {\n            if (!this.memory) {\n                const worker = await init();\n                this.#worker = worker;\n                await Promise.all(this.#engine.filePaths().map((path: string) => registerFileAtWorker(worker, path)));\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":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/javascript/sync/packages/wasm/promise-default.ts#L171-L207","documentation":"pull() long-polls the remote database for new changes and applies them locally. The sync WASM Database only constructs a SyncEngine when the constructor receives a url in DatabaseOpts; when opts.url is null or undefined it opens a plain local NativeDatabase and leaves the internal #engine null (promise-default.ts:61-70). Calling pull() on such a local-only instance throws immediately because there is no remote endpoint to wait on.","triggerScenarios":"Construct with new Database({ path: \"local.db\" }) (no url field, or url: undefined from a misspelled/destructured config), then call await db.pull(). Any code path that reaches pull() without a remote configured hits this guard.","commonSituations":"Local dev/test builds omit the sync URL but share the sync-loop code with production; env-driven config where the variable is missing in CI; migrating from the plain WASM database package to the sync package without adding url/authToken options.","solutions":["Pass url (e.g. \"libsql://...\") together with authToken in DatabaseOpts so the constructor builds the SyncEngine","If local-only operation is intended, remove the pull() call or gate it behind a sync-enabled check derived from the construction options","Log DatabaseOpts at construction to confirm url is not undefined (url: undefined fails the opts.url == null check the same as omitting it)","Check for field-name mismatches such as syncUrl or databaseUrl instead of the expected url key"],"exampleFix":"// before\nconst db = new Database({ path: \"local.db\" });\nawait db.pull(); // throws: sync is disabled\n\n// after\nconst db = new Database({\n  path: \"local.db\",\n  url: \"libsql://your-db.turso.io\",\n  authToken: token,\n});\nawait db.connect();\nawait db.pull();","handlingStrategy":"validation","validationCode":"// The engine exists only when url was provided at construction\nconst opts: DatabaseOpts = { path: \"local.db\", url, authToken };\nconst db = new Database(opts);\nconst syncEnabled = opts.url != null;\n\nif (syncEnabled) {\n  await db.pull();\n}","typeGuard":null,"tryCatchPattern":"try {\n  const pulled = await db.pull();\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"sync is disabled\")) {\n    // local-only database: nothing to pull, degrade gracefully\n    return;\n  }\n  throw err;\n}","preventionTips":["Always pass url plus authToken in DatabaseOpts when the sync loop (pull/push/checkpoint/stats) will run","Remember that url: undefined counts as missing because the constructor tests opts.url == null","Derive a syncEnabled flag from the construction options and guard every sync call with it","In tests, either supply a remote URL or skip the sync loop instead of calling pull on a local-only database"],"tags":["sync","wasm","embedded-replica","configuration","javascript"],"backgroundTag":"sync-not-enabled","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}