{"record":{"id":"95383c91228070b7","repo":"tursodatabase/turso","slug":"remotewritesexperimental-requires-a-non-null-url","errorCode":null,"errorMessage":"remoteWritesExperimental requires a non-null URL","messagePattern":"remoteWritesExperimental requires a non-null URL","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"bindings/javascript/sync/packages/native/promise.ts","lineNumber":48,"sourceCode":"};\n\nfunction memoryIO(): ProtocolIo {\n    let values = new Map();\n    return {\n        async read(path: string): Promise<Buffer | Uint8Array | null> {\n            return values.get(path);\n        },\n        async write(path: string, data: Buffer | Uint8Array): Promise<void> {\n            values.set(path, data);\n        }\n    }\n};\n\nfunction resolveUrl(url: string | (() => string | null)): string {\n    if (typeof url === \"function\") {\n        const resolved = url();\n        if (resolved == null) {\n            throw new Error(\"remoteWritesExperimental requires a non-null URL\");\n        }\n        return resolved;\n    }\n    return url;\n}\n\nclass Database extends DatabasePromise {\n    #engine: any;\n    #guards: SyncEngineGuards | null = null;\n    #runner: Runner | null = null;\n    #remoteWriter: RemoteWriter | null = null;\n    #db: any;\n    constructor(opts: DatabaseOpts) {\n        if (opts.url == null) {\n            const db = new NativeDatabase(opts.path, { tracing: opts.tracing, experimental: opts.experimental }) as any;\n            super(db);\n            this.#db = db;\n            this.#engine = null;","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/javascript/sync/packages/native/promise.ts#L30-L66","documentation":"When remoteWritesExperimental is enabled and opts.url is a function (a lazy URL provider), the Database constructor calls resolveUrl() to get a concrete URL for the RemoteWriter. If invoking the provider returns null or undefined — the convention for 'no remote available' — construction fails with this error, because the remote writer cannot operate without a URL. It happens synchronously in the constructor, before any sync starts.","triggerScenarios":"new Database({ path, url: () => currentUrl, remoteWritesExperimental: true }) where currentUrl is null at construction time (not yet provisioned, feature flag off, offline fallback); a URL provider that reads per-tenant config which is missing for the first request; passing a function that returns undefined due to a typo in the property it reads.","commonSituations":"Multi-tenant apps resolving the sync URL lazily per database; environments where the sync URL env var is missing in dev but present in prod; gradual rollouts that disable sync by returning null from the provider.","solutions":["Ensure the URL provider returns a non-null string before enabling remoteWritesExperimental (resolve it once up front and pass the string).","Defer constructing this Database until the URL is known/provisioned.","If remote writes are optional, construct without remoteWritesExperimental when the provider yields null."],"exampleFix":"// before\nnew Database({ path, url: () => tenantUrl, remoteWritesExperimental: true }); // tenantUrl is null here\n\n// after\nconst url = typeof urlOpt === 'function' ? urlOpt() : urlOpt;\nif (url == null) {\n  throw new Error('sync URL not available yet; construct this database after provisioning');\n}\nnew Database({ path, url, remoteWritesExperimental: true });","handlingStrategy":"validation","validationCode":"const resolvedUrl = typeof urlOpt === 'function' ? urlOpt() : urlOpt;\nif (resolvedUrl == null) {\n  throw new Error('sync URL unavailable; defer remoteWritesExperimental until it is provisioned');\n}\nconst db = new Database({ path, url: resolvedUrl, remoteWritesExperimental: true });","typeGuard":"const isResolvedUrl = (u: unknown): u is string => typeof u === 'string' && u.length > 0;","tryCatchPattern":null,"preventionTips":["Provision the URL before enabling remoteWritesExperimental.","Pass a resolved string URL rather than a provider function when the URL is known at startup.","Log whenever a URL provider returns null so gaps surface early."],"tags":["sync","remote-writes","url","configuration","javascript"],"backgroundTag":"missing-database-url","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}