Skip to content

Astro DB remote build fails with Cloudflare adapter: serializedManifest.rootDir is undefined in workerd runner #16738

@qichunren

Description

@qichunren

Astro Info

Astro                    v6.3.2
Node                     v25.9.0
System                   Linux (x64)
Package Manager          pnpm
Output                   server
Adapter                  @astrojs/cloudflare
Integrations             astro:db
                         @astrojs/db/file-url

Package versions:

{
  "astro": "^6.3.2",
  "@astrojs/cloudflare": "^13.5.1",
  "@astrojs/db": "^0.21.1",
  "wrangler": "^4.90.1"
}

Describe the Bug

astro build --remote fails when using @astrojs/db with @astrojs/cloudflare.

The failure happens during the astro:build:setup hook for astro:db. The remote libSQL/Turso configuration is valid: astro db verify --remote succeeds and reports that the database schema is up to date. astro db push --remote also succeeds.

The build fails while building server entrypoints:

[ERROR] [astro:db] An unhandled error occurred while running the "astro:build:setup" hook
Invalid URL string.
  Stack trace:
    at runInRunnerObject (workers/runner-worker/index.js:107:3)
    at null.<anonymous> (workers/runner-worker/index.js:350:37)

With diagnostic logging added locally around deserializeManifest() in astro/dist/core/app/manifest.js, the invalid manifest URL field is:

[debug invalid manifest URL] rootDir undefined

So the thrown Invalid URL string is caused by:

new URL(serializedManifest.rootDir)

where serializedManifest.rootDir === undefined.

The full stack points to the Cloudflare workerd runner loading virtual:astro:manifest while Astro DB creates its temporary Vite server in astro:build:setup:

TypeError: Invalid URL string.
    at deserializeManifest (.../node_modules/.vite/deps_ssr/chunk-O3AOWAQD.js:50:14)
    at /bundle/\0virtual:astro:manifest:7:44
    at Object.runInlinedModule (workers/runner-worker/index.js:215:4)
    at ModuleRunner.directRequest (workers/runner-worker/vite/module-runner:1215:59)
    at ModuleRunner.cachedRequest (workers/runner-worker/vite/module-runner:1122:73)
    at .../node_modules/.vite/deps_ssr/astro_app_entrypoint_dev.js:92:1

This does not appear to be a Turso/libSQL configuration problem because the Astro DB CLI commands can connect successfully.

Minimal Reproduction

Create an Astro project using @astrojs/cloudflare and @astrojs/db:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
import db from '@astrojs/db';

export default defineConfig({
  output: 'server',
  adapter: cloudflare(),
  integrations: [db({ mode: 'web' })],
});
// wrangler.jsonc
{
  "compatibility_date": "2026-05-14",
  "compatibility_flags": [
    "nodejs_compat",
    "global_fetch_strictly_public"
  ],
  "name": "astro-db-cloudflare-repro",
  "main": "@astrojs/cloudflare/entrypoints/server",
  "assets": {
    "directory": "./dist",
    "binding": "ASSETS"
  },
  "vars": {
    "ASTRO_DB_REMOTE_URL": "https://<database>.turso.io"
  }
}
// db/config.ts
import { column, defineDb, defineTable } from 'astro:db';

export const RequestLog = defineTable({
  columns: {
    id: column.text({ primaryKey: true }),
    requestId: column.text(),
    path: column.text(),
    method: column.text(),
    createdAt: column.date(),
  },
});

export default defineDb({
  tables: { RequestLog },
});
// src/pages/api/hello.ts
import type { APIRoute } from 'astro';
import { db, RequestLog } from 'astro:db';

export const prerender = false;

export const GET: APIRoute = async ({ request }) => {
  const requestId = crypto.randomUUID();
  await db.insert(RequestLog).values({
    id: crypto.randomUUID(),
    requestId,
    path: new URL(request.url).pathname,
    method: request.method,
    createdAt: new Date(),
  });

  return Response.json({ requestId, logged: true });
};

Set these environment variables in .env or the build environment:

ASTRO_DB_REMOTE_URL=https://<database>.turso.io
ASTRO_DB_APP_TOKEN=<token>

Then run:

pnpm astro db verify --remote
pnpm astro db push --remote
pnpm astro build --remote

verify and push succeed, but build --remote fails.

What's the expected result?

astro build --remote should complete successfully when using Astro DB remote mode with the Cloudflare adapter.

What's the actual result?

The build fails in astro:db's astro:build:setup hook because the temporary Vite server enters the Cloudflare workerd runner and tries to deserialize a virtual Astro manifest whose rootDir is undefined.

Notes

A local diagnostic confirmed that serializedManifest.rootDir is undefined at the time deserializeManifest() calls new URL(serializedManifest.rootDir).

This may be related to Astro DB's remote build path creating a temporary Vite server for seed execution even though remote build does not appear to need local seed execution.

No Turso token or private credential is included in this report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P4: importantViolate documented behavior or significantly impacts performance (priority)pkg: cloudflareRelated to the Cloudflare adapterpkg: db

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions