{"record":{"id":"2b8c0915f82dde9c","repo":"thoughtbot/factory_bot","slug":"self-referencing-trait-name","errorCode":null,"errorMessage":"Self-referencing trait '#{@name}'","messagePattern":"Self-referencing trait '#(.+?)'","errorType":"exception","errorClass":"FactoryBot::TraitDefinitionError","httpStatus":null,"severity":"error","filePath":"lib/factory_bot/declaration/implicit.rb","lineNumber":30,"sourceCode":"          name == other.name &&\n          factory == other.factory &&\n          ignored == other.ignored\n      end\n\n      protected\n\n      attr_reader :factory\n\n      private\n\n      def build\n        if FactoryBot.factories.registered?(name)\n          [Attribute::Association.new(name, name, {})]\n        elsif FactoryBot::Internal.sequences.registered?(name)\n          [Attribute::Sequence.new(name, name, @ignored)]\n        elsif @factory.name.to_s == name.to_s\n          message = \"Self-referencing trait '#{@name}'\"\n          raise TraitDefinitionError, message\n        else\n          @factory.inherit_traits([name])\n          []\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":12,"sourceCodeEnd":39,"githubUrl":"https://github.com/thoughtbot/factory_bot/blob/18ae8b581bf55de681c8adb5f74d32787fd2157f/lib/factory_bot/declaration/implicit.rb#L12-L39","documentation":"TraitDefinitionError raised by Declaration::Implicit#build (implicit.rb:23-34) when a bare name inside a trait (or factory) body resolves to nothing registered — not a factory, not a sequence — and equals the enclosing definition's own name. The bare word would make the trait include itself, so factory_bot raises 'Self-referencing trait'. The message says 'trait' even when the same happens in a plain factory body referencing its own name.","triggerScenarios":"Define `trait :admin do admin end` inside `factory :user`, then build with the trait: `FactoryBot.build(:user, :admin)`. The implicit `admin` is not a registered factory or sequence, and the trait's definition name equals 'admin', so TraitDefinitionError 'Self-referencing trait \\'admin\\'' is raised when the trait is compiled. A factory body referencing its own not-yet-registered name (`factory :user do user end`) hits the same branch.","commonSituations":"Writing a trait intended to set a like-named boolean attribute (`admin`, `active`, `verified`) — `trait :active do active end` reads naturally as 'set active' but is a self-include; renaming traits to mirror attribute names; porting older trait definitions that relied on implicit resolution.","solutions":["Give the attribute a value with a block: `trait :admin do admin { true } end`.","Or declare it explicitly: `add_attribute(:admin) { true }`.","If the trait should compose other traits, reference those by name — never itself.","If the goal was an association to a like-named factory, use `association :admin, factory: :admin_user` with an explicit, different factory target."],"exampleFix":"# before\nFactoryBot.define do\n  factory :user do\n    trait :admin do\n      admin   # bare self-reference -> Self-referencing trait 'admin'\n    end\n  end\nend\n\n# after\nFactoryBot.define do\n  factory :user do\n    trait :admin do\n      admin { true }\n    end\n  end\nend","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  FactoryBot.build(:user, :admin)\nrescue FactoryBot::TraitDefinitionError => e\n  raise unless e.message.include?('Self-referencing trait')\n  # give the trait body a block: admin { true }\nend","preventionTips":["When a trait shares its name with an attribute, always assign a value in a block (`admin { true }`).","Never reference the trait's own name bare inside its body.","Run FactoryBot.lint(traits: true) so bad traits fail in CI with the trait name in the message."],"tags":["ruby","factory-bot","trait","self-reference"],"backgroundTag":"circular-reference","analyzedSha":"18ae8b581bf55de681c8adb5f74d32787fd2157f","analyzedAt":"2026-08-21T18:25:33.545Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}