we-promise/sure · error · Thor::Error

Invalid field type '#{field[:type]}' for #{field[:name]}. Mu

Error message

Invalid field type '#{field[:type]}' for #{field[:name]}. Must be one of: text, string, integer, boolean

What it means

Raised as Thor::Error by the provider family generator (lib/generators/provider/family/family_generator.rb:85) during validate_fields when a field declared in the fields argument has a type outside the allowed set: text, string, integer, boolean. The generator's migration template only knows how to emit those four column types, so anything else (datetime, json, decimal, uuid...) is rejected before any file is written.

Source

Thrown at lib/generators/provider/family/family_generator.rb:85

  def validate_fields
    if parsed_fields.empty?
      say "Warning: No fields specified. You'll need to add them manually later.", :yellow
    end

    reserved = parsed_fields.map { |f| f[:name] } & RESERVED_ITEM_COLUMNS
    if reserved.any?
      raise Thor::Error,
            "#{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\"."
    end

    # Validate field types
    parsed_fields.each do |field|
      unless %w[text string integer boolean].include?(field[:type])
        raise Thor::Error, "Invalid field type '#{field[:type]}' for #{field[:name]}. Must be one of: text, string, integer, boolean"
      end
    end
  end

  def generate_migration
    return if options[:skip_migration]

    migration_template "migration.rb.tt",
                       "db/migrate/create_#{table_name}_and_accounts.rb",
                       migration_version: migration_version
  end

  def create_adapter
    return if options[:skip_adapter]

    adapter_path = "app/models/provider/#{file_name}_adapter.rb"

    if File.exist?(adapter_path)

View on GitHub (pinned to e69894adb9)

Solutions

  1. Change the type to one of text, string, integer, boolean — store datetimes as string (ISO8601) and JSON as text, then parse in the model.
  2. Generate with valid fields and hand-edit the resulting migration to add the exotic column afterwards.
  3. Re-run the generator; validation happens before templates, so nothing partial was created.

Example fix

// before
rails g provider:family acme issued_at:datetime

// after
rails g provider:family acme issued_at:string
# then edit the generated model to parse it:
# def issued_at = Time.zone.parse(super) if super
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = %w[text string integer boolean]
fields = fields.each_with_object({}) { |(n, t), h| raise ArgumentError, "#{n}: bad type" unless ALLOWED.include?(t) }

Type guard

type = arg.split(':')[1]
%w[text string integer boolean].include?(type)

Try / catch

begin
  Rails::Generators.invoke 'provider:family', args
rescue Thor::Error => e
  # message names the field and the allowed set; correct and re-run
end

Prevention

When it happens

Trigger: Running rails g provider:family acme issued_at:datetime token:decimal flags:json — any field:type token whose type is not exactly one of text/string/integer/boolean.

Common situations: Porting a provider integration whose API uses timestamps or JSON blobs; muscle memory from rails g model which accepts arbitrary types.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/c2d87f4f45b7cc0e. Report an issue: GitHub.