{"id":"9765878c714bcf6a","repo":"sequelize/sequelize","slug":"value-for-key-option-cannot-be-an-empty-strin","errorCode":null,"errorMessage":"Value for \"${key}\" option cannot be an empty string","messagePattern":"Value for \"(.+?)\" option cannot be an empty string","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/model-definition.ts","lineNumber":305,"sourceCode":"\n      rawAttributes[attributeName] = rawAttribute;\n\n      if (rawAttribute.field) {\n        fieldToColumn();\n      }\n    }\n\n    // setup names of timestamp attributes\n    if (this.options.timestamps) {\n      for (const key of ['createdAt', 'updatedAt', 'deletedAt'] as const) {\n        if (!['undefined', 'string', 'boolean'].includes(typeof this.options[key])) {\n          throw new Error(\n            `Value for \"${key}\" option must be a string or a boolean, got ${typeof this.options[key]}`,\n          );\n        }\n\n        if (this.options[key] === '') {\n          throw new Error(`Value for \"${key}\" option cannot be an empty string`);\n        }\n      }\n\n      if (this.options.createdAt !== false) {\n        this.timestampAttributeNames.createdAt =\n          typeof this.options.createdAt === 'string' ? this.options.createdAt : 'createdAt';\n\n        this.#readOnlyAttributeNames.add(this.timestampAttributeNames.createdAt);\n      }\n\n      if (this.options.updatedAt !== false) {\n        this.timestampAttributeNames.updatedAt =\n          typeof this.options.updatedAt === 'string' ? this.options.updatedAt : 'updatedAt';\n        this.#readOnlyAttributeNames.add(this.timestampAttributeNames.updatedAt);\n      }\n\n      if (this.options.paranoid && this.options.deletedAt !== false) {\n        this.timestampAttributeNames.deletedAt =","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/sequelize/sequelize/blob/7e1deec499d5afbb8d1877c2f4d545cead1214ec/packages/core/src/model-definition.ts#L287-L323","documentation":"At model-definition.ts:304-306 the constructor rejects an empty string for createdAt/updatedAt/deletedAt, because `''` is neither a valid attribute name nor the `false` value used to disable a timestamp. An empty string would produce an attribute with no usable name.","triggerScenarios":"Passing `{ timestamps: true, createdAt: '' }` (or updatedAt/deletedAt) — often from a config variable that resolved to an empty string.","commonSituations":"Environment-driven config (`process.env.CREATED_AT`) that is unset and defaults to `''`; conditional logic that builds the option name but yields empty.","solutions":["Use `false` to disable the timestamp.","Provide a non-empty string to rename it.","Normalize empty config values to `undefined` so Sequelize uses the default."],"exampleFix":"// before\nUser.init(attrs, { sequelize, timestamps: true, createdAt: process.env.CREATED_AT || '' });\n\n// after\nUser.init(attrs, { sequelize, timestamps: true, createdAt: process.env.CREATED_AT || undefined });","handlingStrategy":"validation","validationCode":"function assertNoEmptyTimestampStrings(opts) {\n  if (!opts.timestamps) return;\n  for (const key of ['createdAt', 'updatedAt', 'deletedAt']) {\n    if (opts[key] === '') throw new Error(`${key} cannot be an empty string; use false to disable.`);\n  }\n}\nassertNoEmptyTimestampStrings(modelOptions);","typeGuard":"function isNonEmptyStringOrFalse(v) {\n  return v === undefined || v === false || (typeof v === 'string' && v.length > 0);\n}","tryCatchPattern":null,"preventionTips":["Normalize env-driven config (e.g. process.env.CREATED_AT) to undefined when empty.","Use false explicitly to disable a timestamp rather than an empty string.","Add a config sanity check in test setup."],"tags":["config","timestamps"],"analyzedSha":"7e1deec499d5afbb8d1877c2f4d545cead1214ec","analyzedAt":"2026-08-03T18:58:44.549Z","schemaVersion":2}