tursodatabase/turso · error · LibsqlError

MISSING_URL

MISSING_URL

Error message

Missing required 'url' configuration option

What it means

validateConfig() requires a truthy url; after the unsupported-options check, a config with no url (undefined, null or empty string) throws LibsqlError code MISSING_URL at createClient() time. The serverless client is remote-only, so the URL is the one piece of configuration it cannot operate without.

Solutions

  1. Set the url option from the environment (e.g. libsql://mydb-myorg.turso.io) and confirm the variable exists in every deploy environment
  2. Fail fast at cold start: check process.env.TURSO_DATABASE_URL and throw a descriptive error before createClient
  3. Use platform-correct env access (process.env on Vercel/Node, env bindings on Cloudflare Workers) rather than assuming Node semantics

Example fix

// before
const client = createClient({
  url: process.env.TURSO_DATABASE_URL, // undefined in prod
  authToken: process.env.TURSO_AUTH_TOKEN,
});

// after
const url = process.env.TURSO_DATABASE_URL;
if (!url) {
  throw new Error('TURSO_DATABASE_URL is not set - configure it for this environment');
}
const client = createClient({ url, authToken: process.env.TURSO_AUTH_TOKEN });
Defensive patterns

Strategy: validation

Validate before calling

const url = process.env.TURSO_DATABASE_URL;
if (!url) {
  throw new Error('TURSO_DATABASE_URL is not set - add it to this environment (Vercel/Cloudflare/Netlify)');
}
const client = createClient({ url, authToken: process.env.TURSO_AUTH_TOKEN });

Type guard

function hasDatabaseUrl(url: string | undefined): url is string {
  return typeof url === 'string' && url.length > 0;
}

Prevention

When it happens

Trigger: createClient({}) or createClient({ authToken }) with the url key absent; url sourced from an environment variable that is not set in the deployed environment, yielding undefined or ''.

Common situations: TURSO_DATABASE_URL not configured in Vercel/Cloudflare/Netlify for the preview or production environment while it exists locally; typo'd variable name; deploying before wiring secrets.

Related errors


AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20). Data as JSON: /api/errors/7942dcffbc668671. Report an issue: GitHub.

Appendix: source

Thrown at serverless/javascript/src/compat.ts:220

    }
    if (config.fetch !== undefined) {
      unsupportedOptions.push({ key: 'fetch', value: config.fetch });
    }
    if (config.concurrency !== undefined) {
      unsupportedOptions.push({ key: 'concurrency', value: config.concurrency });
    }

    if (unsupportedOptions.length > 0) {
      const optionsList = unsupportedOptions.map(opt => `'${opt.key}'`).join(', ');
      throw new LibsqlError(
        `Unsupported configuration options: ${optionsList}. Only 'url', 'authToken', and 'remoteEncryptionKey' are supported in the serverless compatibility layer.`,
        "UNSUPPORTED_CONFIG"
      );
    }

    // Validate required options
    if (!config.url) {
      throw new LibsqlError("Missing required 'url' configuration option", "MISSING_URL");
    }
  }

  get closed(): boolean {
    return this._closed;
  }

  get protocol(): string {
    return "http";
  }

  private normalizeStatement(stmt: InStatement): { sql: string; args: any[] } {
    if (typeof stmt === 'string') {
      return { sql: stmt, args: [] };
    }
    
    const args = stmt.args || [];
    if (Array.isArray(args)) {

View on GitHub (pinned to 6c72522679)