tursodatabase/turso · error · Error

HTTP request missing URL: no URL in request and no baseUrl i

Error message

HTTP request missing URL: no URL in request and no baseUrl in context

What it means

When the sync engine emits an HTTP IO item, processHttpRequest() must produce a full URL: it prefers the baseUrl from the connect() context (getBaseUrl(context)) and falls back to the URL embedded in the request itself. If both are absent there is nowhere to send the request, and it throws before any network activity. This is a configuration error, not a network failure.

Source

Thrown at bindings/react-native/src/internal/ioProcessor.ts:162

    return context.baseUrl() ?? null;
  }

  return context.baseUrl;
}

/**
 * Process an HTTP request using fetch()
 *
 * @param item - The IO item
 * @param context - IO context with auth and URL information
 */
async function processHttpRequest(item: NativeSyncIoItem, context: IoContext): Promise<void> {
  const request = item.getHttpRequest();

  // Resolve base URL: prefer context.baseUrl (from opts), fall back to request.url
  const rawBaseUrl = getBaseUrl(context) ?? request.url;
  if (!rawBaseUrl) {
    throw new Error('HTTP request missing URL: no URL in request and no baseUrl in context');
  }

  // Normalize URL (libsql:// -> https://)
  const baseUrl = normalizeUrl(rawBaseUrl);

  // Build full URL by combining base URL with path
  let fullUrl = baseUrl;
  if (request.path) {
    // Ensure proper URL formatting (avoid double slashes, ensure single slash)
    if (baseUrl.endsWith('/') && request.path.startsWith('/')) {
      fullUrl = baseUrl + request.path.substring(1);
    } else if (!baseUrl.endsWith('/') && !request.path.startsWith('/')) {
      fullUrl = baseUrl + '/' + request.path;
    } else {
      fullUrl = baseUrl + request.path;
    }
  }

View on GitHub (pinned to bad083fafb)

Solutions

  1. Pass a valid url in the connect() options so the IO context has a baseUrl
  2. Verify the url value is a non-empty string at runtime (log it before connect) and that env vars are actually loaded
  3. Check the option name and nesting against the connect() signature — a typo'd key silently leaves url undefined
  4. If the request should be purely local, avoid operations that require remote pages until a url is configured

Example fix

// before
const db = await connect({ path: dbPath }); // later throws: HTTP request missing URL

// after
const db = await connect({
  path: dbPath,
  url: 'https://my-db-my-org.turso.io',
  authToken: myToken,
});
Defensive patterns

Strategy: validation

Validate before calling

function assertConnectOpts(opts: { url?: string; authToken?: string }): void {
  if (typeof opts.url !== 'string' || opts.url.trim() === '') {
    throw new Error('connect(): url is required for sync IO — got ' + JSON.stringify(opts.url));
  }
}

assertConnectOpts(opts);
const db = await connect(opts);

Type guard

function hasSyncUrl(opts: unknown): opts is { url: string } {
  return typeof (opts as { url?: unknown })?.url === 'string' &&
    (opts as { url: string }).url.length > 0;
}

Prevention

When it happens

Trigger: Calling connect({ path }) with no url and then triggering IO (any query needing remote pages, or sync); an opts object whose url is undefined or empty string (e.g. a missing environment variable); constructing the Database with a context that never carried a baseUrl.

Common situations: Forgetting url in local-first usage that later needs remote pages; env vars not loaded before connect() in React Native (no automatic .env support); passing url only in a nested/wrongly named option key.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/9061718ba693d31f. Report an issue: GitHub.