All guidesMore providers: databases, auth, hosting, email and payments
On this page

Turso error

Turso

LibsqlError: URL_INVALID: The URL "undefined" is not in a valid format

By Ohad Krispin, founder of VibeRaven · LinkedIn

"LibsqlError: URL_INVALID: The URL 'undefined' is not in a valid format" means createClient from @libsql/client received undefined as its url, so the variable you pass in, usually TURSO_DATABASE_URL, had no value where the code ran. The client parses the string before it connects, and the message prints whatever it got: an empty string gives the same error with nothing between the quotes. On Vercel it happens when the value lives only in .env.local, which create-next-app keeps out of git, when it is set for a different environment, when the code reads another name, or when createClient runs in browser code. Add TURSO_DATABASE_URL and TURSO_AUTH_TOKEN in Vercel for Production and Preview, then redeploy. Reproduced with @libsql/client 0.18.0 on 2026-10-31.

Why does it work locally and fail on Vercel?

Next.js loads .env and .env.local into process.env on your machine, and its docs say the default create-next-app template adds all .env files to .gitignore. Vercel never receives those files. It reads the variables in the project settings, each one applied to the Production, Preview or Development environments you selected, and a change reaches only new deployments. The non-null assertion in createClient({ url: process.env.TURSO_DATABASE_URL! }) hides the problem, because it satisfies TypeScript and still passes undefined. Check the value yourself and fail with your own message.

const url = process.env.TURSO_DATABASE_URL
if (!url) throw new Error('TURSO_DATABASE_URL is not set')

export const db = createClient({ url, authToken: process.env.TURSO_AUTH_TOKEN })

What if the code falls back to file:local.db?

A fallback such as process.env.TURSO_DATABASE_URL ?? "file:local.db" removes this error and opens a local SQLite file instead. Turso's docs show file: URLs for local use. In our run the Node client opened file:local.db without any account, and a path in a missing folder failed with ConnectionFailed and "Unable to open connection to local database". The web client, @libsql/client/web, rejects file: with URL_SCHEME_NOT_SUPPORTED, and Turso's docs say it does not support local file URLs. Vercel's guide on files in functions recommends object storage such as Vercel Blob for writing files, so a file: database is not where production data should live. Turso's Vercel page describes the remote HTTP route as working in any runtime, including edge functions, without filesystem access.

URL_SCHEME_NOT_SUPPORTED: The client that uses Web standard APIs supports only "libsql:", "wss:", "ws:", "https:" and "http:" URLs, got "file:".

Is createClient running in the browser?

Next.js says variables without the NEXT_PUBLIC_ prefix are only available in the Node.js environment. A createClient call inside a file marked "use client" gets undefined even when Vercel holds the value. The libsql-client-ts issue 238 with this exact title came from a stack trace in the browser bundle, and the maintainer answered that the error usually means no URL was provided. Do not rename the variable to NEXT_PUBLIC_ to make it appear: Next.js inlines those values into the JavaScript sent to the browser, and the auth token would go with it. Move the query into a route handler, a server action or a server component.

Checklist

How to fix it, then check the fix

  1. 01
    Find every place the client is created and every name it reads:
    grep -rnE "createClient|TURSO_DATABASE_URL|TURSO_AUTH_TOKEN|file:" --exclude-dir=node_modules --exclude-dir=.next .
  2. 02Make the client fail with your own message when the URL is missing, as in the first section, and remove any file: fallback from the production path.
  3. 03
    Get the values. The Turso CLI prints the database URL, and a new token comes from the tokens command:
    turso db show <database-name> --url
    turso db tokens create <database-name>
  4. 04
    Add both in Vercel for each environment that runs the app, using the names your code reads. Turso's docs use TURSO_DATABASE_URL and TURSO_AUTH_TOKEN:
    vercel env add TURSO_DATABASE_URL production
    vercel env add TURSO_AUTH_TOKEN production
    vercel env add TURSO_DATABASE_URL preview
    vercel env add TURSO_AUTH_TOKEN preview
  5. 05Keep createClient in server-only code, never in a file marked "use client", and add both names to .env.example without values.
  6. 06Redeploy, then load a route that runs a query: it answers with data, not a LibsqlError in the function log.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Why does the message put undefined in quotes?

The parser builds it as The URL, then the value in single quotes, then is not in a valid format (libsql-core, uri.ts). It prints whatever string it was given, so a variable set to nothing shows two quotes with nothing between them.

Can I use file:local.db as the production database on Vercel?

The Node client will open it, but it is a SQLite file on the function's disk, not your Turso database, and the web client rejects file: URLs. Vercel recommends object storage for writing files. Use the remote Turso URL in production and keep file: for local work.