{"record":{"id":"2a7e07edb8d33a27","repo":"thoughtbot/factory_bot","slug":"unexpected-block-passed-to-name-association-i","errorCode":null,"errorMessage":"Unexpected block passed to '#{name}' association in '#{@definition.name}' factory","messagePattern":"Unexpected block passed to '#(.+?)' association in '#(.+?)' factory","errorType":"exception","errorClass":"FactoryBot::AssociationDefinitionError","httpStatus":null,"severity":"error","filePath":"lib/factory_bot/definition_proxy.rb","lineNumber":157,"sourceCode":"    #\n    #   factory :post do\n    #     association :author, factory: :user\n    #   end\n    #\n    # Arguments:\n    # * name: +Symbol+\n    #   The name of this attribute.\n    # * options: +Hash+\n    #\n    # Options:\n    # * factory: +Symbol+ or +String+\n    #    The name of the factory to use when building the associated instance.\n    #    If no name is given, the name of the attribute is assumed to be the\n    #    name of the factory. For example, a \"user\" association will by\n    #    default use the \"user\" factory.\n    def association(name, *options)\n      if block_given?\n        raise AssociationDefinitionError.new(\n          \"Unexpected block passed to '#{name}' association \" \\\n          \"in '#{@definition.name}' factory\"\n        )\n      else\n        declaration = Declaration::Association.new(name, *options)\n        @definition.declare_attribute(declaration)\n      end\n    end\n\n    def to_create(&block)\n      @definition.to_create(&block)\n    end\n\n    def skip_create\n      @definition.skip_create\n    end\n\n    def factory(name, options = {}, &block)","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/thoughtbot/factory_bot/blob/18ae8b581bf55de681c8adb5f74d32787fd2157f/lib/factory_bot/definition_proxy.rb#L139-L175","documentation":"AssociationDefinitionError raised by DefinitionProxy#association (definition_proxy.rb:155-160) when a block is passed to `association`. Associations are purely declarative; factory_bot cannot evaluate a block for them, and the guard fails fast during the FactoryBot.define block instead of silently ignoring the block.","triggerScenarios":"Write `association :author, factory: :user do |a| ... end` (or the short form `author factory: :user do ... end`) inside a factory body. The definition block raises immediately with \"Unexpected block passed to 'author' association in 'post' factory\".","commonSituations":"Trying to customize the associated record inline, a habit carried over from `create(:user) { |u| ... }` result blocks; converting an attribute block into an association while leaving the block attached; refactoring shared setups where the block contained extra attribute assignments.","solutions":["Remove the block and pass overrides directly: `association :author, factory: :user, name: 'Jane'`.","Move the customization into a trait on the target factory and pass the trait: `association :author, :with_name, factory: :user`.","Use after(:build) / after(:create) callbacks on the parent factory to mutate the associated record.","If you need dynamic construction, use the allowed block form `author { association(:author, name: 'Jane') }` — a Dynamic attribute whose block calls association."],"exampleFix":"# before\nFactoryBot.define do\n  factory :post do\n    association :author, factory: :user do |author|\n      author.name = 'Jane'\n    end\n  end\nend\n\n# after\nFactoryBot.define do\n  factory :post do\n    association :author, factory: :user, name: 'Jane'\n  end\nend","handlingStrategy":"validation","validationCode":"# wrapper that refuses blocks on associations before factory_bot sees them\ndef association!(name, *options, &block)\n  raise ArgumentError, \"association #{name} takes no block\" if block\n  association(name, *options)\nend","typeGuard":"->(blk) { blk.nil? }","tryCatchPattern":"begin\n  FactoryBot.define { #...\n }\nrescue FactoryBot::AssociationDefinitionError => e\n  raise unless e.message.include?('Unexpected block passed')\n  # move the block body into overrides, a trait, or an after(:build) callback\nend","preventionTips":["Keep `association` declarations one-line; put customization in traits or callbacks.","Use `attr { association(:x, ...) }` when association construction must be dynamic.","Treat the create-block habit (`create(:x) { |o| ... }`) as call-site only — never inside definitions."],"tags":["ruby","factory-bot","association","block","dsl"],"backgroundTag":"unexpected-block-passed","analyzedSha":"18ae8b581bf55de681c8adb5f74d32787fd2157f","analyzedAt":"2026-08-21T18:25:33.545Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}