{"id":"f1f8f26415873703","repo":"drizzle-team/drizzle-orm","slug":"we-don-t-support-params-for-sql-default-values","errorCode":null,"errorMessage":"we don't support params for `sql` default values","messagePattern":"we don't support params for `sql` default values","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-kit/src/serializer/utils.ts","lineNumber":20,"sourceCode":"import { CasingCache, toCamelCase, toSnakeCase } from 'drizzle-orm/casing';\nimport { CasingType } from '../cli/validations/common';\n\nexport function getColumnCasing(\n\tcolumn: { keyAsName: boolean; name: string | undefined },\n\tcasing: CasingType | undefined,\n) {\n\tif (!column.name) return '';\n\treturn !column.keyAsName || casing === undefined\n\t\t? column.name\n\t\t: casing === 'camelCase'\n\t\t? toCamelCase(column.name)\n\t\t: toSnakeCase(column.name);\n}\n\nexport const sqlToStr = (sql: SQL, casing: CasingType | undefined) => {\n\treturn sql.toQuery({\n\t\tescapeName: () => {\n\t\t\tthrow new Error(\"we don't support params for `sql` default values\");\n\t\t},\n\t\tescapeParam: () => {\n\t\t\tthrow new Error(\"we don't support params for `sql` default values\");\n\t\t},\n\t\tescapeString: () => {\n\t\t\tthrow new Error(\"we don't support params for `sql` default values\");\n\t\t},\n\t\tcasing: new CasingCache(casing),\n\t}).sql;\n};\n\nexport const sqlToStrGenerated = (sql: SQL, casing: CasingType | undefined) => {\n\treturn sql.toQuery({\n\t\tescapeName: () => {\n\t\t\tthrow new Error(\"we don't support params for `sql` default values\");\n\t\t},\n\t\tescapeParam: () => {\n\t\t\tthrow new Error(\"we don't support params for `sql` default values\");","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-kit/src/serializer/utils.ts#L2-L38","documentation":"`sqlToStr` renders an `SQL` column default back to a plain SQL string for schema serialization. drizzle-kit refuses to render any identifier token (`escapeName`) inside a `sql` default, because the static serializer has no naming context to resolve it. This fires from any serializer (pg/mysql/sqlite/singlestore/gel) when a `default(sql`...`)` expression contains a quoted name placeholder.","triggerScenarios":"Defining a column with `default(sql`<some identifier>`)` where the expression triggers the `escapeName` callback of `SQL.toQuery`, e.g. embedding a column/table name via `sql.identifier` inside a default.","commonSituations":"Writing `default(sql`now()`)` works (no params), but `default(sql`gen_random_uuid()`)` with a column reference, or composing defaults with `sql.identifier(...)`, triggers it. Most commonly hit by users trying to reference another column in a default expression.","solutions":["Rewrite the `sql` default to a constant expression with no identifier/param/string placeholders, e.g. `default(sql`now()`)`.","If a dynamic name is required, use a plain string default or a `defaultFn` instead of `default(sql`...`)`.","Avoid embedding `sql.identifier(...)` inside column defaults."],"exampleFix":"// before\ncreated: timestamp('created', { mode: 'date' }).default(sql`${sql.identifier('now')}()`),\n// after\ncreated: timestamp('created', { mode: 'date' }).default(sql`now()`),","handlingStrategy":"validation","validationCode":"// Refuse sql defaults that contain identifier nodes before generate\nimport { SQL } from 'drizzle-orm';\nfunction assertPureSqlDefault(expr: SQL) {\n  let hit = false;\n  expr.toQuery({\n    escapeName: () => { hit = true; return ''; },\n    escapeParam: () => { hit = true; return ''; },\n    escapeString: () => { hit = true; return ''; },\n    casing: { toSnake: (s) => s, toCamel: (s) => s, column: '' } as any,\n  });\n  if (hit) throw new Error('sql default contains unsupported token');\n}","typeGuard":"import { SQL } from 'drizzle-orm';\nfunction isPureSqlDefault(expr: SQL): boolean {\n  let bad = false;\n  try {\n    expr.toQuery({\n      escapeName: () => { bad = true; return ''; },\n      escapeParam: () => { bad = true; return ''; },\n      escapeString: () => { bad = true; return ''; },\n      casing: { toSnake: (s) => s, toCamel: (s) => s, column: '' } as any,\n    });\n  } catch { return false; }\n  return !bad;\n}","tryCatchPattern":"try {\n  await import('drizzle-kit').then((k) => k.generate(config));\n} catch (e) {\n  if ((e as Error).message.includes(\"params for `sql` default values\")) {\n    // strip sql.identifier/param/string from the offending default\n  }\n  throw e;\n}","preventionTips":["Keep sql defaults free of identifiers/params/strings; use plain SQL text.","Prefer defaultFn for dynamic defaults."],"tags":["drizzle-kit","serializer","sql-default","schema"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}