{"record":{"id":"7942dcffbc668671","repo":"tursodatabase/turso","slug":"missing-url","errorCode":"MISSING_URL","errorMessage":"Missing required 'url' configuration option","messagePattern":"Missing required 'url' configuration option","errorType":"exception","errorClass":"LibsqlError","httpStatus":null,"severity":"error","filePath":"serverless/javascript/src/compat.ts","lineNumber":223,"sourceCode":"    }\n    if (config.fetch !== undefined) {\n      unsupportedOptions.push({ key: 'fetch', value: config.fetch });\n    }\n    if (config.concurrency !== undefined) {\n      unsupportedOptions.push({ key: 'concurrency', value: config.concurrency });\n    }\n\n    if (unsupportedOptions.length > 0) {\n      const optionsList = unsupportedOptions.map(opt => `'${opt.key}'`).join(', ');\n      throw new LibsqlError(\n        `Unsupported configuration options: ${optionsList}. Only 'url', 'authToken', and 'remoteEncryptionKey' are supported in the serverless compatibility layer.`,\n        \"UNSUPPORTED_CONFIG\"\n      );\n    }\n\n    // Validate required options\n    if (!config.url) {\n      throw new LibsqlError(\"Missing required 'url' configuration option\", \"MISSING_URL\");\n    }\n  }\n\n  get closed(): boolean {\n    return this._closed;\n  }\n\n  get protocol(): string {\n    return \"http\";\n  }\n\n  private normalizeStatement(stmt: InStatement): { sql: string; args: any[] } {\n    if (typeof stmt === 'string') {\n      return { sql: stmt, args: [] };\n    }\n    \n    const args = stmt.args || [];\n    if (Array.isArray(args)) {","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/serverless/javascript/src/compat.ts#L205-L241","documentation":"Thrown by the serverless compatibility layer's client constructor validation (compat.ts) when the config object has no 'url'. The compat layer only accepts 'url', 'authToken', and 'remoteEncryptionKey', and 'url' is the single required option, so an empty or missing url fails fast at construction time with code MISSING_URL before any network I/O happens.","triggerScenarios":"Calling createClient(new Client(...)) with an empty object, with only { authToken }, or with url set to an empty string (any falsy value fails the !config.url check). Most commonly: building config from process.env.TURSO_URL when that variable is undefined because it was never exported or the .env file was not loaded before construction.","commonSituations":"Missing or misnamed environment variable in CI, Docker, or serverless deployments (TURSO_DB_URL vs TURSO_URL); .env loaded after the client module is imported at top level; a config spread like { ...base, url: undefined } that clobbers url; porting code from @libsql/client where the url was optional for local file databases.","solutions":["Set the url option explicitly, usually from the environment: createClient({ url: process.env.TURSO_URL, authToken: process.env.TURSO_AUTH_TOKEN })","Verify the environment variable exists at process start and fail fast with a clear message if TURSO_URL is unset","Ensure .env loading (e.g. dotenv/config) happens before the module that constructs the client is imported","Check for typos in the env var name across local, CI, and deploy environments"],"exampleFix":"// before\nconst client = createClient({ authToken: process.env.TURSO_AUTH_TOKEN });\n// throws LibsqlError MISSING_URL: Missing required 'url' configuration option\n\n// after\nif (!process.env.TURSO_URL) {\n  throw new Error('TURSO_URL is not set — configure it before creating the client');\n}\nconst client = createClient({\n  url: process.env.TURSO_URL,\n  authToken: process.env.TURSO_AUTH_TOKEN,\n});","handlingStrategy":"validation","validationCode":"function assertClientConfig(config: Partial<Config>): Config {\n  if (typeof config.url !== 'string' || config.url.length === 0) {\n    throw new Error('TURSO_URL is not set — add it to the environment before creating the client');\n  }\n  return config as Config;\n}\n\nconst client = createClient(\n  assertClientConfig({ url: process.env.TURSO_URL, authToken: process.env.TURSO_AUTH_TOKEN }),\n);","typeGuard":"function hasValidUrl(config: unknown): config is Config {\n  return (\n    typeof config === 'object' && config !== null &&\n    typeof (config as Config).url === 'string' &&\n    (config as Config).url.length > 0\n  );\n}","tryCatchPattern":"try {\n  const client = createClient(config);\n} catch (e) {\n  if (e instanceof LibsqlError && e.code === 'MISSING_URL') {\n    throw new Error('Database URL missing — check TURSO_URL in this environment');\n  }\n  throw e;\n}","preventionTips":["Validate required env vars at process start and crash loudly instead of constructing a half-configured client","Load .env files before importing modules that create clients (e.g. import 'dotenv/config' at the entry point)","Keep one config-building function as the single source of truth so url can never be silently omitted","Add a startup smoke check in CI that instantiates the client to catch missing env vars before deploy"],"tags":["config","validation","serverless","env-var","constructor"],"backgroundTag":"missing-required-config-option","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}