tursodatabase/turso · error · Error
remoteWritesExperimental requires a non-null URL
Error message
remoteWritesExperimental requires a non-null URL
What it means
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.
Source
Thrown at bindings/javascript/sync/packages/native/promise.ts:48
};
function memoryIO(): ProtocolIo {
let values = new Map();
return {
async read(path: string): Promise<Buffer | Uint8Array | null> {
return values.get(path);
},
async write(path: string, data: Buffer | Uint8Array): Promise<void> {
values.set(path, data);
}
}
};
function resolveUrl(url: string | (() => string | null)): string {
if (typeof url === "function") {
const resolved = url();
if (resolved == null) {
throw new Error("remoteWritesExperimental requires a non-null URL");
}
return resolved;
}
return url;
}
class Database extends DatabasePromise {
#engine: any;
#guards: SyncEngineGuards | null = null;
#runner: Runner | null = null;
#remoteWriter: RemoteWriter | null = null;
#db: any;
constructor(opts: DatabaseOpts) {
if (opts.url == null) {
const db = new NativeDatabase(opts.path, { tracing: opts.tracing, experimental: opts.experimental }) as any;
super(db);
this.#db = db;
this.#engine = null;View on GitHub (pinned to bad083fafb)
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.
Example fix
// before
new Database({ path, url: () => tenantUrl, remoteWritesExperimental: true }); // tenantUrl is null here
// after
const url = typeof urlOpt === 'function' ? urlOpt() : urlOpt;
if (url == null) {
throw new Error('sync URL not available yet; construct this database after provisioning');
}
new Database({ path, url, remoteWritesExperimental: true }); Defensive patterns
Strategy: validation
Validate before calling
const resolvedUrl = typeof urlOpt === 'function' ? urlOpt() : urlOpt;
if (resolvedUrl == null) {
throw new Error('sync URL unavailable; defer remoteWritesExperimental until it is provisioned');
}
const db = new Database({ path, url: resolvedUrl, remoteWritesExperimental: true }); Type guard
const isResolvedUrl = (u: unknown): u is string => typeof u === 'string' && u.length > 0;
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- sync is disabled as database was opened without sync support
- remoteWritesExperimental requires a non-null URL
- remoteWritesExperimental requires a non-null URL
- remoteWritesExperimental requires a non-null URL
- remoteWritesExperimental requires a non-null URL
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/95383c91228070b7.
Report an issue: GitHub.