thoughtbot/factory_bot · error · ArgumentError
Association '#{name}' received an invalid factory argument.
Error message
Association '#{name}' received an invalid factory argument.
Did you mean? 'factory: :#{factory_name.name}' What it means
Raised by factory_bot when an association's factory option is not a factory name but an implicit Declaration object. Writing `author factory: user` (bare user, no colon) makes DefinitionProxy#method_missing treat `user` as an implicit attribute reference, and that Declaration::Implicit is stored as the factory argument of the association declaration. The guard raise_if_arguments_are_declarations! (association.rb:39-45) detects it when declarations are built, so the error surfaces on the first build/create/lint of the factory, not at definition time.
Source
Thrown at lib/factory_bot/declaration/association.rb:41
private
attr_reader :factory_name, :overrides, :traits
def build
raise_if_arguments_are_declarations!
[
Attribute::Association.new(
name,
factory_name,
[traits, overrides].flatten
)
]
end
def raise_if_arguments_are_declarations!
if factory_name.is_a?(Declaration)
raise ArgumentError.new(<<~MSG)
Association '#{name}' received an invalid factory argument.
Did you mean? 'factory: :#{factory_name.name}'
MSG
end
overrides.each do |attribute, value|
if value.is_a?(Declaration)
raise ArgumentError.new(<<~MSG)
Association '#{name}' received an invalid attribute override.
Did you mean? '#{attribute}: :#{value.name}'
MSG
end
end
end
end
end
end
View on GitHub (pinned to 18ae8b581b)
Solutions
- Symbolize the factory target: `association :author, factory: :user` (or the short `author factory: :user`).
- If the attribute name already matches the target factory, drop options entirely: `author` implicitly uses the :author factory.
- Audit the rest of the options hash — the same typo pattern also triggers the sibling 'invalid attribute override' error.
- Add FactoryBot.lint(traits: true) to CI so declaration errors surface deterministically instead of at first use.
Example fix
# before
FactoryBot.define do
factory :post do
author factory: user # bare user becomes a Declaration, not :user
end
end
# after
FactoryBot.define do
factory :post do
author factory: :user
end
end Defensive patterns
Strategy: validation
Validate before calling
# before defining, verify association factory targets are symbols/strings
options = { factory: :user }
bad = options.reject { |_, v| v.is_a?(Symbol) || v.is_a?(String) }
raise ArgumentError, "non-symbol association option values: #{bad.keys}" unless bad.empty? Type guard
->(v) { v.is_a?(Symbol) || v.is_a?(String) } Try / catch
begin
FactoryBot.build(:post)
rescue ArgumentError => e
raise unless e.message.include?('invalid factory argument')
# a factory option lost its ':' — symbolize it in the association declaration
end Prevention
- Always write association factory targets as symbols: `factory: :user`, never `factory: user`.
- Run FactoryBot.lint(traits: true) in CI so declaration errors surface before runtime.
- Copy association declarations from a known-good factory instead of typing option hashes by hand.
When it happens
Trigger: Define `FactoryBot.define { factory :post do author factory: user end }` (missing the colon before user), then call FactoryBot.build(:post). The bare method call inside the options hash produces a Declaration that becomes factory_name; Association#build raises ArgumentError "Association 'author' received an invalid factory argument. Did you mean? 'factory: :user'".
Common situations: Hand-typing association options and dropping the colon; copy-paste from docs or older examples where the leading colon is easy to lose; refactors that turn symbol values into bare references. Often first seen in CI because definition files only fail once a factory is actually built or linted.
Related errors
- Association '#{name}' received an invalid attribute override
- Unexpected block passed to '#{name}' association in '#{@defi
- Self-referencing association '#{attribute.name}' in '#{attri
- count missing for #{strategy_name}_list
- undefined method '#{name}' in '#{@definition.name}' factory
AI-assisted analysis of thoughtbot/factory_bot@18ae8b581b (2026-08-21).
Data as JSON: /api/errors/010e06fcaea71367.
Report an issue: GitHub.