{"record":{"id":"3b40d70a33580b8d","repo":"thoughtbot/factory_bot","slug":"the-following-factories-are-invalid-lines-join","errorCode":null,"errorMessage":"The following factories are invalid:\n\n#{lines.join(\"\\n\")}","messagePattern":"The following factories are invalid:\n\n#(.+?)","errorType":"exception","errorClass":"FactoryBot::InvalidFactoryError","httpStatus":null,"severity":"error","filePath":"lib/factory_bot/linter.rb","lineNumber":13,"sourceCode":"module FactoryBot\n  class Linter\n    def initialize(factories, strategy: :create, traits: false, verbose: false)\n      @factories_to_lint = factories\n      @factory_strategy = strategy\n      @traits = traits\n      @verbose = verbose\n      @invalid_factories = calculate_invalid_factories\n    end\n\n    def lint!\n      if invalid_factories.any?\n        raise InvalidFactoryError, error_message\n      end\n    end\n\n    private\n\n    attr_reader :factories_to_lint, :invalid_factories, :factory_strategy\n\n    def calculate_invalid_factories\n      factories_to_lint.each_with_object(Hash.new([])) do |factory, result|\n        errors = lint(factory)\n        result[factory] |= errors unless errors.empty?\n      end\n    end\n\n    class FactoryError\n      def initialize(wrapped_error, factory)\n        @wrapped_error = wrapped_error\n        @factory = factory","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/thoughtbot/factory_bot/blob/18ae8b581bf55de681c8adb5f74d32787fd2157f/lib/factory_bot/linter.rb#L1-L31","documentation":"InvalidFactoryError raised by FactoryBot.lint (Linter#lint!, linter.rb:11-15). The linter instantiates every registered factory — and each trait when traits: true — using the chosen strategy (default :create), wrapped in a rollback transaction when ActiveRecord is defined, collects all failures, and raises one aggregate error. Each line of the message is `* factory_name - wrapped message (ErrorClass)` (or `factory+trait`) so the per-factory root causes are listed.","triggerScenarios":"Run `FactoryBot.lint` or `FactoryBot.lint!(traits: true, verbose: true)` (typically a CI rake task); any factory whose build/create raises — model validations, missing columns after a migration, associations pointing at undefined factories, broken sequences — is aggregated into 'The following factories are invalid:' with one line per failure.","commonSituations":"Schema drift: factories not updated after migrations or new validations (presence/uniqueness breaking old factories); a factory renamed or deleted while associations still reference it; trait combinations never exercised by the test suite; linting newly enabled on a legacy codebase for the first time.","solutions":["Read the per-line wrapped errors in the message — each names the factory, the underlying exception message, and its class; fix those factories first.","Re-run with verbose: true for full backtraces and traits: true to cover trait failures.","Fix root causes: add required attributes/transients after model changes, correct association targets, repair sequences.","Keep the lint task in CI so invalid factories fail the build before developers hit them at runtime."],"exampleFix":"# before\nfactory :user do\n  name { 'Alice' } # email column added + presence validation -> factory fails lint\nend\n\n# after\nfactory :user do\n  name { 'Alice' }\n  email { sequence(:email) { |n| \"alice#{n}@example.com\" } }\nend","handlingStrategy":"try-catch","validationCode":"# lint only the factories touched by a change, before running the full suite\nFactoryBot.lint(FactoryBot.factories.select { |f| f.name.to_s.start_with?('user') })","typeGuard":null,"tryCatchPattern":"begin\n  FactoryBot.lint(traits: true, verbose: true)\nrescue FactoryBot::InvalidFactoryError => e\n  warn e.message # lists each factory, wrapped message, and error class\n  exit 1\nend","preventionTips":["Add a factory_bot:lint rake task to CI so schema/factory drift fails the build early.","Run with traits: true and verbose: true locally to see backtraces and trait failures.","Update factories in the same PR that changes models, validations, or migrations."],"tags":["ruby","factory-bot","linting","ci","test-data"],"backgroundTag":"factory-lint-failure","analyzedSha":"18ae8b581bf55de681c8adb5f74d32787fd2157f","analyzedAt":"2026-08-21T18:25:33.545Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}