{"record":{"id":"94bacd54bb50f1cb","repo":"thoughtbot/factory_bot","slug":"association-name-received-an-invalid-attribut","errorCode":null,"errorMessage":"Association '#{name}' received an invalid attribute override.\nDid you mean? '#{attribute}: :#{value.name}'","messagePattern":"Association '#(.+?)' received an invalid attribute override\\.\nDid you mean\\? '#(.+?): :#(.+?)'","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/factory_bot/declaration/association.rb","lineNumber":49,"sourceCode":"          Attribute::Association.new(\n            name,\n            factory_name,\n            [traits, overrides].flatten\n          )\n        ]\n      end\n\n      def raise_if_arguments_are_declarations!\n        if factory_name.is_a?(Declaration)\n          raise ArgumentError.new(<<~MSG)\n            Association '#{name}' received an invalid factory argument.\n            Did you mean? 'factory: :#{factory_name.name}'\n          MSG\n        end\n\n        overrides.each do |attribute, value|\n          if value.is_a?(Declaration)\n            raise ArgumentError.new(<<~MSG)\n              Association '#{name}' received an invalid attribute override.\n              Did you mean? '#{attribute}: :#{value.name}'\n            MSG\n          end\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":31,"sourceCodeEnd":59,"githubUrl":"https://github.com/thoughtbot/factory_bot/blob/18ae8b581bf55de681c8adb5f74d32787fd2157f/lib/factory_bot/declaration/association.rb#L31-L59","documentation":"Raised by factory_bot when a value inside an association's options hash is an implicit Declaration instead of a literal. With `author factory: :user, invalid_attribute: implicit_trait`, the bare `implicit_trait` is dispatched through DefinitionProxy#method_missing and becomes a Declaration::Implicit stored as the override value; raise_if_arguments_are_declarations! (association.rb:47-54) catches it when the declaration list is built (first build/lint) and suggests the symbol form.","triggerScenarios":"Define `FactoryBot.define { factory :post do author factory: :user, invalid_attribute: implicit_trait end }` and run FactoryBot.build(:post). Any non-literal, non-symbol value in the association options hash that resolves to a Declaration (bare name, no colon) triggers \"Association 'author' received an invalid attribute override. Did you mean? 'invalid_attribute: :implicit_trait'\".","commonSituations":"Writing association overrides the same way as implicit trait references inside factory bodies; dropping colons when hand-writing option hashes; refactoring a working association line and leaving a bare reference behind; errors appear only when the factory is first built, so they surface late in CI.","solutions":["Symbolize the override value: `association :author, factory: :user, invalid_attribute: :implicit_trait`.","If the value is not meant to be a factory/trait/sequence name, use a literal (string, integer, boolean) or a block-computed attribute on the parent factory instead.","Check every key in the same hash — one bare reference usually means more are nearby.","Run FactoryBot.lint(traits: true) in CI to catch all declaration mistakes at build time."],"exampleFix":"# before\nFactoryBot.define do\n  factory :post do\n    author factory: :user, invalid_attribute: implicit_trait\n  end\nend\n\n# after\nFactoryBot.define do\n  factory :post do\n    association :author, factory: :user, invalid_attribute: :implicit_trait\n  end\nend","handlingStrategy":"validation","validationCode":"# verify every override value in association options is a literal, not a bare reference\noptions = { factory: :user, invalid_attribute: :implicit_trait }\nbad = options.reject { |_, v| [Symbol, String, Integer, Float, TrueClass, FalseClass, NilClass].any? { |t| v.is_a?(t) } }\nraise ArgumentError, \"suspicious override values: #{bad.keys}\" unless bad.empty?","typeGuard":"->(v) { v.is_a?(Symbol) || v.is_a?(String) || v.is_a?(Numeric) || [true, false, nil].include?(v) }","tryCatchPattern":"begin\n  FactoryBot.build(:post)\nrescue ArgumentError => e\n  raise unless e.message.include?('invalid attribute override')\n  # an override value lost its ':' — symbolize it in the association options\nend","preventionTips":["Symbolize or quote every override value inside association option hashes.","Never nest bare names in option hashes — association options accept literals, symbols, and strings only.","Lint factories in CI to catch declaration mistakes before they reach a test run."],"tags":["ruby","factory-bot","association","overrides","argumenterror"],"backgroundTag":"wrong-argument-type","analyzedSha":"18ae8b581bf55de681c8adb5f74d32787fd2157f","analyzedAt":"2026-08-21T18:25:33.545Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}