## Rails 8.0.4.1 (March 23, 2026) ##

*   Reject scientific notation in NumberConverter

    [CVE-2026-33176]

    *Jean Boussier*

*   Fix `SafeBuffer#%` to preserve unsafe status

    [CVE-2026-33170]

    *Jean Boussier*

*   Improve performance of NumberToDelimitedConverter

    [CVE-2026-33169]

    *Jean Boussier*


## Rails 8.0.4 (October 28, 2025) ##

*   Fix `Enumerable#sole` to return the full tuple instead of just the first element of the tuple.

    *Olivier Bellone*

*   Fix parallel tests hanging when worker processes die abruptly.

    Previously, if a worker process was killed (e.g., OOM killed, `kill -9`) during parallel
    test execution, the test suite would hang forever waiting for the dead worker.

    *Joshua Young*

*   Fix `NameError` when `class_attribute` is defined on instance singleton classes.

    Previously, calling `class_attribute` on an instance's singleton class would raise
    a `NameError` when accessing the attribute through the instance.

    ```ruby
    object = MyClass.new
    object.singleton_class.class_attribute :foo, default: "bar"
    object.foo # previously raised NameError, now returns "bar"
    ```

    *Joshua Young*


## Rails 8.0.3 (September 22, 2025) ##

*   `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unnecessary reloads with time travel test helpers

    *Jan Grodowski*

*   Fix `ActiveSupport::BroadcastLogger` from executing a block argument for each logger (tagged, info, etc.).

    *Jared Armstrong*

*   Make `ActiveSupport::Logger` `#freeze`-friendly.

    *Joshua Young*

*   Fix `ActiveSupport::HashWithIndifferentAccess#transform_keys!` removing defaults.

    *Hartley McGuire*

*   Fix `ActiveSupport::HashWithIndifferentAccess#tranform_keys!` to handle collisions.

    If the transformation would result in a key equal to another not yet transformed one,
    it would result in keys being lost.

    Before:

    ```ruby
    >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
    => {"c" => 1}
    ```

    After:

    ```ruby
    >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
    => {"b" => 1, "c" => 2}
    ```

    *Jason T Johnson*, *Jean Boussier*

*   Fix `ActiveSupport::Cache::MemCacheStore#read_multi` to handle network errors.

    This method specifically wasn't handling network errors like other codepaths.

    *Alessandro Dal Grande*

*   Fix configuring `RedisCacheStore` with `raw: true`.

    *fatkodima*

*   Fix `Enumerable#sole` for infinite collections.

    *fatkodima*


## Rails 8.0.2.1 (August 13, 2025) ##

*   No changes.


## Rails 8.0.2 (March 12, 2025) ##

*   Fix setting `to_time_preserves_timezone` from `new_framework_defaults_8_0.rb`.

    *fatkodima*

*   Fix Active Support Cache `fetch_multi` when local store is active.

    `fetch_multi` now properly yield to the provided block for missing entries
    that have been recorded as such in the local store.

    *Jean Boussier*

*   Fix execution wrapping to report all exceptions, including `Exception`.

    If a more serious error like `SystemStackError` or `NoMemoryError` happens,
    the error reporter should be able to report these kinds of exceptions.

    *Gannon McGibbon*

*   Fix `RedisCacheStore` and `MemCacheStore` to also handle connection pool related errors.

    These errors are rescued and reported to `Rails.error`.

    *Jean Boussier*

*   Fix `ActiveSupport::Cache#read_multi` to respect version expiry when using local cache.

    *zzak*

*   Fix `ActiveSupport::MessageVerifier` and `ActiveSupport::MessageEncryptor` configuration of `on_rotation` callback.

    ```ruby
    verifier.rotate(old_secret).on_rotation { ... }
    ```

    Now both work as documented.

    *Jean Boussier*

*   Fix `ActiveSupport::MessageVerifier` to always be able to verify both URL-safe and URL-unsafe payloads.

    This is to allow transitioning seemlessly from either configuration without immediately invalidating
    all previously generated signed messages.

    *Jean Boussier*, *Florent Beaurain*, *Ali Sepehri*

*   Fix `cache.fetch` to honor the provided expiry when `:race_condition_ttl` is used.

    ```ruby
    cache.fetch("key", expires_in: 1.hour, race_condition_ttl: 5.second) do
      "something"
    end
    ```

    In the above example, the final cache entry would have a 10 seconds TTL instead
    of the requested 1 hour.

    *Dhia*

*   Better handle procs with splat arguments in `set_callback`.

    *Radamés Roriz*

*   Fix `String#mb_chars` to not mutate the receiver.

    Previously it would call `force_encoding` on the receiver,
    now it dups the receiver first.

    *Jean Boussier*

*   Improve `ErrorSubscriber` to also mark error causes as reported.

    This avoid some cases of errors being reported twice, notably in views because of how
    errors are wrapped in `ActionView::Template::Error`.

    *Jean Boussier*

*   Fix `Module#module_parent_name` to return the correct name after the module has been named.

    When called on an anonymous module, the return value wouldn't change after the module was given a name
    later by being assigned to a constant.

    ```ruby
    mod = Module.new
    mod.module_parent_name # => "Object"
    MyModule::Something = mod
    mod.module_parent_name # => "MyModule"
    ```

    *Jean Boussier*


## Rails 8.0.1 (December 13, 2024) ##

*   Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceeded by multibyte characters.

    *Martin Emde*

*   Restore the ability to decorate methods generated by `class_attribute`.

    It always has been complicated to use Module#prepend or an alias method chain
    to decorate methods defined by `class_attribute`, but became even harder in 8.0.

    This capability is now supported for both reader and writer methods.

    *Jean Boussier*


## Rails 8.0.0.1 (December 10, 2024) ##

*   No changes.


## Rails 8.0.0 (November 07, 2024) ##

*   No changes.


## Rails 8.0.0.rc2 (October 30, 2024) ##

*   No changes.


## Rails 8.0.0.rc1 (October 19, 2024) ##

*   Remove deprecated support to passing an array of strings to `ActiveSupport::Deprecation#warn`.

    *Rafael Mendonça França*

*   Remove deprecated support to setting `attr_internal_naming_format` with a `@` prefix.

    *Rafael Mendonça França*

*   Remove deprecated `ActiveSupport::ProxyObject`.

    *Rafael Mendonça França*

*   Don't execute i18n watcher on boot. It shouldn't catch any file changes initially,
    and unnecessarily slows down boot of applications with lots of translations.

    *Gannon McGibbon*, *David Stosik*

*   Fix `ActiveSupport::HashWithIndifferentAccess#stringify_keys` to stringify all keys not just symbols.

    Previously:

    ```ruby
    { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
    ```

    After this change:

    ```ruby
    { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2
    ```

    This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding
    to not backport the fix and to make the change in a major release.

    *Jean Boussier*

## Rails 8.0.0.beta1 (September 26, 2024) ##

*   Include options when instrumenting `ActiveSupport::Cache::Store#delete` and `ActiveSupport::Cache::Store#delete_multi`.

    *Adam Renberg Tamm*

*   Print test names when running `rails test -v` for parallel tests.

    *John Hawthorn*, *Abeid Ahmed*

*   Deprecate `Benchmark.ms` core extension.

    The `benchmark` gem will become bundled in Ruby 3.5

    *Earlopain*

*   `ActiveSupport::TimeWithZone#inspect` now uses ISO 8601 style time like `Time#inspect`

    *John Hawthorn*

*   `ActiveSupport::ErrorReporter#report` now assigns a backtrace to unraised exceptions.

    Previously reporting an un-raised exception would result in an error report without
    a backtrace. Now it automatically generates one.

    *Jean Boussier*

*   Add `escape_html_entities` option to `ActiveSupport::JSON.encode`.

    This allows for overriding the global configuration found at
    `ActiveSupport.escape_html_entities_in_json` for specific calls to `to_json`.

    This should be usable from controllers in the following manner:
    ```ruby
    class MyController < ApplicationController
      def index
        render json: { hello: "world" }, escape_html_entities: false
      end
    end
    ```

    *Nigel Baillie*

*   Raise when using key which can't respond to `#to_sym` in `EncryptedConfiguration`.

    As is the case when trying to use an Integer or Float as a key, which is unsupported.

    *zzak*

*   Deprecate addition and since between two `Time` and `ActiveSupport::TimeWithZone`.

    Previously adding time instances together such as `10.days.ago + 10.days.ago` or `10.days.ago.since(10.days.ago)` produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1.

    *Nick Schwaderer*

*   Support rfc2822 format for Time#to_fs & Date#to_fs.

    *Akshay Birajdar*

*   Optimize load time for `Railtie#initialize_i18n`. Filter `I18n.load_path`s passed to the file watcher to only those
    under `Rails.root`. Previously the watcher would grab all available locales, including those in gems
    which do not require a watcher because they won't change.

    *Nick Schwaderer*

*   Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results
    by these values.

    *Igor Depolli*

*   Improve error message when using `assert_difference` or `assert_changes` with a
    proc by printing the proc's source code (MRI only).

    *Richard Böhme*, *Jean Boussier*

*   Add a new configuration value `:zone` for `ActiveSupport.to_time_preserves_timezone` and rename the previous `true` value to `:offset`. The new default value is `:zone`.

    *Jason Kim*, *John Hawthorn*

*   Align instrumentation `payload[:key]` in ActiveSupport::Cache to follow the same pattern, with namespaced and normalized keys.

    *Frederik Erbs Spang Thomsen*

*   Fix `travel_to` to set usec 0 when `with_usec` is `false` and the given argument String or DateTime.

    *mopp*

Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activesupport/CHANGELOG.md) for previous changes.
