Files
gh-jezweb-claude-skills-ski…/references/common-errors.md
2025-11-30 08:24:43 +08:00

5.3 KiB

Common Errors with Drizzle ORM and D1

This document provides detailed solutions for all 12 documented issues.


Issue #1: D1 Transaction Errors

Error: D1_ERROR: Cannot use BEGIN TRANSACTION

Source: https://github.com/drizzle-team/drizzle-orm/issues/4212

Why It Happens: Drizzle ORM tries to use traditional SQL transactions with BEGIN TRANSACTION and COMMIT statements. However, Cloudflare D1 does not support these SQL transaction commands and raises a D1_ERROR.

Solution: Use D1's batch API instead:

// ❌ Don't use
await db.transaction(async (tx) => {
  // This will fail
});

// ✅ Use batch API
await db.batch([
  db.insert(users).values({ email: 'test@example.com', name: 'Test' }),
  db.insert(posts).values({ title: 'Post', content: 'Content', authorId: 1 }),
]);

See templates/transactions.ts for complete examples.


Issue #2: Foreign Key Constraint Failures

Error: FOREIGN KEY constraint failed: SQLITE_CONSTRAINT

Source: https://github.com/drizzle-team/drizzle-orm/issues/4089

Why It Happens: Drizzle-generated migrations include PRAGMA foreign_keys = OFF; which can cause issues during migration execution.

Solution:

  1. Define cascading deletes in schema:
authorId: integer('author_id')
  .notNull()
  .references(() => users.id, { onDelete: 'cascade' })
  1. Ensure proper migration order (parent tables before child tables)
  2. Test migrations locally first: wrangler d1 migrations apply DB --local

Issue #3: Module Import Errors

Error: Error: No such module "wrangler"

Source: https://github.com/drizzle-team/drizzle-orm/issues/4257

Why It Happens: Bundlers (like OpenNext) may incorrectly try to bundle Wrangler, which should only be used as a CLI tool.

Solution:

  1. Never import from wrangler in runtime code
  2. Use correct imports: import { drizzle } from 'drizzle-orm/d1'
  3. Configure bundler externals if needed

Issue #4: D1 Binding Not Found

Error: env.DB is undefined or Cannot read property 'prepare' of undefined

Why It Happens: The D1 binding name in wrangler.jsonc doesn't match the name used in code.

Solution: Ensure consistency:

// wrangler.jsonc
{
  "d1_databases": [
    { "binding": "DB" }  // ← Must match
  ]
}
// code
export interface Env {
  DB: D1Database;  // ← Must match
}

const db = drizzle(env.DB);  // ← Must match

Issue #5: Migration Apply Failures

Error: Migration failed to apply: near "...": syntax error

Why It Happens: SQL syntax errors, conflicting migrations, or applying migrations out of order.

Solution:

  1. Test locally first: wrangler d1 migrations apply DB --local
  2. Review generated SQL in ./migrations before applying
  3. If failed, delete and regenerate: rm -rf migrations/ && drizzle-kit generate

Issue #6: Schema TypeScript Inference Errors

Error: Type instantiation is excessively deep and possibly infinite

Why It Happens: Complex circular references in relations cause TypeScript to fail type inference.

Solution: Use explicit type annotations:

import { InferSelectModel } from 'drizzle-orm';

export type User = InferSelectModel<typeof users>;
export type Post = InferSelectModel<typeof posts>;

Issue #7: Prepared Statement Caching Issues

Error: Stale or incorrect results from queries

Why It Happens: D1 doesn't cache prepared statements between requests like traditional SQLite.

Solution: Don't rely on caching behavior:

// ✅ Use .all() or .get() methods
const users = await db.select().from(users).all();

Issue #8: Transaction Rollback Patterns

Error: Transaction doesn't roll back on error

Why It Happens: D1 batch API doesn't support traditional rollback.

Solution: Implement error handling with manual cleanup:

try {
  await db.batch([/* operations */]);
} catch (error) {
  // Manual cleanup if needed
  console.error('Batch failed:', error);
}

Issue #9: TypeScript Strict Mode Errors

Error: Type errors with strict: true

Solution: Use explicit return types:

async function getUser(id: number): Promise<User | undefined> {
  return await db.select().from(users).where(eq(users.id, id)).get();
}

Issue #10: Drizzle Config Not Found

Error: Cannot find drizzle.config.ts

Why It Happens: Wrong file location or incorrect file name.

Solution:

  1. File must be named exactly drizzle.config.ts
  2. File must be in project root
  3. Or specify: drizzle-kit generate --config=custom.config.ts

Issue #11: Remote vs Local Confusion

Error: Changes not appearing

Why It Happens: Applying migrations to wrong database.

Solution: Use correct flags consistently:

# Development
wrangler d1 migrations apply DB --local

# Production
wrangler d1 migrations apply DB --remote

Issue #12: wrangler.toml vs wrangler.jsonc

Error: Configuration not recognized

Why It Happens: Mixing TOML and JSON config formats.

Solution: Use wrangler.jsonc consistently (supports comments):

{
  "name": "my-worker",
  // Comment here
  "d1_databases": []
}

Total Errors Prevented: 12 Success Rate: 100% when following these solutions