Skip to content

Undefined method attribute_before_type_cast  #105

@tiagotex

Description

@tiagotex

For the last 3 months, we got 13 occurrences of similar errors originating from typed store, one example:

NameError: undefined method `can_perform_before_type_cast' for class `Activity' (NameError)

        undef_method(method) if method_defined?(method)
        ^^^^^^^^^^^^
  from activerecord-typedstore (7d6dce4b7029) lib/active_record/typed_store/behavior.rb:30:in `undef_method'
  from activerecord-typedstore (7d6dce4b7029) lib/active_record/typed_store/behavior.rb:30:in `undefine_before_type_cast_method'
  from activerecord-typedstore (7d6dce4b7029) lib/active_record/typed_store/behavior.rb:22:in `block in define_typed_store_attribute_methods'
  from set.rb:511:in `each_key'
  from set.rb:511:in `each'
  from activerecord-typedstore (7d6dce4b7029) lib/active_record/typed_store/behavior.rb:20:in `define_typed_store_attribute_methods'
  from activerecord-typedstore (7d6dce4b7029) lib/active_record/typed_store/behavior.rb:10:in `define_attribute_methods'
  from activerecord (7.0.8) lib/active_record/core.rb:765:in `init_internals'
  from activerecord (7.0.8) lib/active_record/associations.rb:323:in `init_internals'
  from activerecord (7.0.8) lib/active_record/core.rb:502:in `init_with_attributes'
  from activerecord (7.0.8) lib/active_record/persistence.rb:537:in `instantiate_instance_of'
  from activerecord (7.0.8) lib/active_record/querying.rb:76:in `block (2 levels) in _load_from_sql'
  from activerecord (7.0.8) lib/active_record/result.rb:69:in `each'
  from activerecord (7.0.8) lib/active_record/result.rb:69:in `each'
  from activerecord (7.0.8) lib/active_record/querying.rb:76:in `map'
  from activerecord (7.0.8) lib/active_record/querying.rb:76:in `block in _load_from_sql'
  from activerecord (7.0.8) lib/active_record/querying.rb:71:in `_load_from_sql'
  from activerecord (7.0.8) lib/active_record/relation.rb:954:in `instantiate_records'
  from activerecord (7.0.8) lib/active_record/relation.rb:917:in `block in exec_queries'
  from activerecord (7.0.8) lib/active_record/relation.rb:962:in `skip_query_cache_if_necessary'
  from activerecord (7.0.8) lib/active_record/relation.rb:908:in `exec_queries'
  from activerecord (7.0.8) lib/active_record/association_relation.rb:44:in `exec_queries'
  from activerecord (7.0.8) lib/active_record/relation.rb:695:in `load'
  from activerecord (7.0.8) lib/active_record/relation.rb:250:in `records'
  from activerecord (7.0.8) lib/active_record/relation.rb:245:in `to_ary'
  from activerecord (7.0.8) lib/active_record/associations/association.rb:224:in `find_target'
  from activerecord (7.0.8) lib/active_record/associations/singular_association.rb:44:in `find_target'
  from activerecord (7.0.8) lib/active_record/associations/association.rb:173:in `load_target'
  from activerecord (7.0.8) lib/active_record/associations/association.rb:67:in `reload'
  from activerecord (7.0.8) lib/active_record/associations/singular_association.rb:11:in `reader'
  from activerecord (7.0.8) lib/active_record/associations/builder/association.rb:104:in `activity'
  from app/models/parent_activity.rb:301:in `check_activity'

Our Activity model has 3 typed stores, and the error seems to be triggered by random attributes inside the typed stores, not a particular one. We also have some other models with a single typed store, and we haven't seen any issues arising from those.

The crash comes from:

def undefine_before_type_cast_method(attribute)
  # because it mess with ActionView forms, see #14.
  method = "#{attribute}_before_type_cast"
  undef_method(method) if method_defined?(method)
end

It was added as a response to this bug report in ActionView forms: #14

It seems like method_defined? is returning true, but when we run undef_method, the method might already be removed...

We use Puma and Sidekiq, and can observe the issue on both processes. I suspect this is a thread-safety issue caused by ActiveRecord.

Sadly, I don't know enough about the active record internals to figure out if a race condition can happen.

Has someone else come across the same issue or has some pointers?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions