{"record":{"id":"4119de36092ab764","repo":"we-promise/sure","slug":"reserved-join-reserved-one-is-a","errorCode":null,"errorMessage":"#{reserved.join(', ')} #{reserved.one? ? 'is' : 'are'} already provided by the items table. Remove #{reserved.one? ? 'it' : 'them'} from the command: the standard column serves the same purpose, and redeclaring would abort db:migrate with \"you can't define an already defined column\".","messagePattern":"#(.+?) #(.+?) already provided by the items table\\. Remove #(.+?) from the command: the standard column serves the same purpose, and redeclaring would abort db:migrate with \"you can't define an already defined column\"\\.","errorType":"exception","errorClass":"Thor::Error","httpStatus":null,"severity":"error","filePath":"lib/generators/provider/family/family_generator.rb","lineNumber":75,"sourceCode":"  argument :fields, type: :array, default: [], banner: \"field:type[:secret] field:type[:secret]\"\n\n  class_option :skip_migration, type: :boolean, default: false, desc: \"Skip generating migration\"\n  class_option :skip_routes, type: :boolean, default: false, desc: \"Skip adding routes\"\n  class_option :skip_view, type: :boolean, default: false, desc: \"Skip generating view\"\n  class_option :skip_controller, type: :boolean, default: false, desc: \"Skip generating controller\"\n  class_option :skip_adapter, type: :boolean, default: false, desc: \"Skip generating adapter\"\n  class_option :type, type: :string, default: \"investment\",\n               enum: %w[banking investment],\n               desc: \"Provider type: banking (transactions only) or investment (holdings + activities)\"\n\n  def validate_fields\n    if parsed_fields.empty?\n      say \"Warning: No fields specified. You'll need to add them manually later.\", :yellow\n    end\n\n    reserved = parsed_fields.map { |f| f[:name] } & RESERVED_ITEM_COLUMNS\n    if reserved.any?\n      raise Thor::Error,\n            \"#{reserved.join(', ')} #{reserved.one? ? 'is' : 'are'} already provided by the \" \\\n            \"items table. Remove #{reserved.one? ? 'it' : 'them'} from the command: the \" \\\n            \"standard column serves the same purpose, and redeclaring would abort db:migrate \" \\\n            \"with \\\"you can't define an already defined column\\\".\"\n    end\n\n    # Validate field types\n    parsed_fields.each do |field|\n      unless %w[text string integer boolean].include?(field[:type])\n        raise Thor::Error, \"Invalid field type '#{field[:type]}' for #{field[:name]}. Must be one of: text, string, integer, boolean\"\n      end\n    end\n  end\n\n  def generate_migration\n    return if options[:skip_migration]\n\n    migration_template \"migration.rb.tt\",","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/lib/generators/provider/family/family_generator.rb#L57-L93","documentation":"Raised as Thor::Error by the provider family generator (lib/generators/provider/family/family_generator.rb:75) when any --fields entry names a column already provided by the generated items table (RESERVED_ITEM_COLUMNS, which includes family_id, institution_id, etc.). Declaring such a column would make the generated migration abort db:migrate with Rails' \"you can't define an already defined column\", so the generator refuses up front.","triggerScenarios":"Running rails g provider:family MyProvider fields like family_id:string or institution_id:uuid — names the generator itself emits into the item migration template.","commonSituations":"Copy-pasting an existing provider's column list into the generator command without stripping the standard columns; assuming you must declare the family foreign key yourself.","solutions":["Remove the listed reserved name(s) from the fields argument — the generator adds them automatically.","If you need a DIFFERENT concept, rename your field (e.g. external_family_ref:string) instead of reusing the reserved name.","Run rails g provider:family --help to see the field syntax and the provider template's standard columns."],"exampleFix":"// before\nrails g provider:family acme family_id:string api_key:text\n\n// after\nrails g provider:family acme api_key:text","handlingStrategy":"validation","validationCode":"reserved = %w[family_id institution_id] # mirror RESERVED_ITEM_COLUMNS\nfields = requested_fields.reject { |f| reserved.include?(f.split(':').first) }","typeGuard":"field_name = arg.split(':').first\n!Provider::FamilyGenerator::RESERVED_ITEM_COLUMNS.include?(field_name)","tryCatchPattern":"begin\n  Rails::Generators.invoke 'provider:family', args\nrescue Thor::Error => e\n  abort e.message # message already tells you which column(s) to drop\nend","preventionTips":["Read the generator's RESERVED_ITEM_COLUMNS list before composing a fields argument.","The standard columns (family_id, institution_id, ...) are emitted automatically — never redeclare them.","Validate failed: Thor::Error aborts before any template is written, so just fix the args and re-run."],"tags":["rails","generator","thor","reserved-columns","cli"],"backgroundTag":"generator-invalid-argument","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}