drizzle-team/drizzle-orm · error · Error

Custom default not found for ${column.schema}.${column.table

Error message

Custom default not found for ${column.schema}.${column.table}.${column.column}

What it means

Studio's `defaults` handler resolves each requested column against the `customDefaults` array built from columns that declare `defaultFn`. If the frontend requests a default for a `{schema, table, column}` triple that has no matching entry, drizzle-kit throws. This indicates a mismatch between the schema Studio introspected at init and the column it is now asking about (casing, schema, or table-name drift).

Source

Thrown at drizzle-kit/src/serializer/studio.ts:812

		if (type === 'tproxy') {
			const result = await transactionProxy(body.data);
			return c.json(JSON.parse(jsonStringify(result)));
		}

		if (type === 'defaults') {
			const columns = body.data;

			const result = columns.map((column) => {
				const found = customDefaults.find((d) => {
					return (
						d.schema === column.schema
						&& d.table === column.table
						&& d.column === column.column
					);
				});

				if (!found) {
					throw new Error(
						`Custom default not found for ${column.schema}.${column.table}.${column.column}`,
					);
				}

				const value = found.func();

				return {
					...column,
					value,
				};
			});

			return c.json(JSON.parse(jsonStringify(result)));
		}

		throw new Error(`Unknown type: ${type}`);
	});

View on GitHub (pinned to b7862528fd)

Solutions

  1. Restart `drizzle-kit studio` so the schema and custom defaults are re-introspected.
  2. Ensure the casing config in `drizzle.config.ts` matches the schema and the Studio client version.
  3. Verify the column actually defines `defaultFn` (e.g. `default(() => crypto.randomUUID())`), not just a raw `default('x')`.

Example fix

// before - column casing mismatch causes lookup miss
// config uses camelCase but DB column is snake_case
// after - align casing and restart Studio
casing: 'snake_case'
Defensive patterns

Strategy: validation

Validate before calling

// Confirm a defaultFn exists for the column before requesting default
function columnHasDefault(col: { defaultFn?: unknown }) {
  return typeof col.defaultFn === 'function';
}

Type guard

interface CustomDefaultLike { schema: string; table: string; column: string; func: () => unknown; }
function isCustomDefault(v: unknown): v is CustomDefaultLike {
  return !!v && typeof (v as any).func === 'function';
}

Try / catch

try {
  await insertWithDefaults();
} catch (e) {
  if ((e as Error).message.startsWith('Custom default not found')) {
    // restart Studio to re-introspect, or set the value manually
  }
  throw e;
}

Prevention

When it happens

Trigger: Inserting a row in Studio for a column whose `defaultFn`-bearing column was renamed, recased, or moved to another schema between init and insert; or a bug where the requested column casing does not match the prepared default's casing.

Common situations: Using `camelCase` casing config and the Studio frontend sending snake_case names (or vice-versa), schema edited after Studio started (hot reload), or a version mismatch between drizzle-kit and the Studio UI.

Related errors


AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03). Data as JSON: /data/errors/b0b7beac495a03cb.json. Report an issue: GitHub.