{"id":"f02c41c783760c5b","repo":"sequelize/sequelize","slug":"symbol-attributes-are-not-supported","errorCode":null,"errorMessage":"Symbol attributes are not supported","messagePattern":"Symbol attributes are not supported","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/model-definition.ts","lineNumber":275,"sourceCode":"        }),\n      ),\n    );\n\n    // error check options\n    for (const [validatorName, validator] of getAllOwnEntries(this.options.validate)) {\n      if (typeof validator !== 'function') {\n        throw new TypeError(\n          `Members of the validate option must be functions. Model: ${this.modelName}, error with validate member ${String(validatorName)}`,\n        );\n      }\n    }\n\n    // attributes that will be added at the start of this.rawAttributes (id)\n    const rawAttributes = pojo<{ [attributeName: string]: AttributeOptions<M> }>();\n\n    for (const [attributeName, rawAttributeOrDataType] of getAllOwnEntries(attributesOptions)) {\n      if (typeof attributeName === 'symbol') {\n        throw new TypeError('Symbol attributes are not supported');\n      }\n\n      let rawAttribute: AttributeOptions<M>;\n      try {\n        rawAttribute = this.sequelize.normalizeAttribute(rawAttributeOrDataType);\n      } catch (error) {\n        throw new BaseError(\n          `An error occurred for attribute ${attributeName} on model ${this.modelName}.`,\n          { cause: error },\n        );\n      }\n\n      rawAttributes[attributeName] = rawAttribute;\n\n      if (rawAttribute.field) {\n        fieldToColumn();\n      }\n    }","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/sequelize/sequelize/blob/7e1deec499d5afbb8d1877c2f4d545cead1214ec/packages/core/src/model-definition.ts#L257-L293","documentation":"At model-definition.ts:273-276 the constructor iterates the attributes object using `getAllOwnEntries`, which can surface Symbol keys. If an attribute key is a symbol rather than a string, a TypeError is thrown because Sequelize attributes must be named by strings (they become column references, query keys, and JS property names).","triggerScenarios":"Defining attributes with a computed Symbol key, e.g. `User.init({ [Symbol('x')]: DataTypes.STRING }, ...)`; spreading a map/object whose own keys include a symbol.","commonSituations":"Programmatic attribute generation using symbols as keys; mixing framework metadata symbols into the attribute definition object.","solutions":["Use plain string keys for all attributes.","Strip symbol keys before passing the attributes object to init/define."],"exampleFix":"// before\nUser.init({ [Symbol('id')]: { type: DataTypes.INTEGER, primaryKey: true } }, { sequelize, modelName: 'User' });\n\n// after\nUser.init({ id: { type: DataTypes.INTEGER, primaryKey: true } }, { sequelize, modelName: 'User' });","handlingStrategy":"type-guard","validationCode":"function assertStringKeys(attrs) {\n  for (const key of Reflect.ownKeys(attrs)) {\n    if (typeof key !== 'string') {\n      throw new Error(`Attribute key must be a string, got ${String(key)}.`);\n    }\n  }\n}\nassertStringKeys(attributes);","typeGuard":"function hasOnlyStringKeys(obj) {\n  return Reflect.ownKeys(obj).every(k => typeof k === 'string');\n}","tryCatchPattern":null,"preventionTips":["Build attribute objects with plain string literals, never symbols.","Strip metadata symbols before passing framework objects as attribute definitions.","Validate dynamically-generated attribute maps before init."],"tags":["schema","config","naming"],"analyzedSha":"7e1deec499d5afbb8d1877c2f4d545cead1214ec","analyzedAt":"2026-08-03T18:58:44.549Z","schemaVersion":2}