Skip to content

Fix NoMethodError when encoding with invalid: :replace option#9182

Merged
headius merged 2 commits intojruby:masterfrom
khasinski:fix-encoding-undefined-conversion-error
Jan 30, 2026
Merged

Fix NoMethodError when encoding with invalid: :replace option#9182
headius merged 2 commits intojruby:masterfrom
khasinski:fix-encoding-undefined-conversion-error

Conversation

@khasinski
Copy link
Contributor

Summary

  • Fixes NoMethodError: undefined method '[]' for nil when encoding a string with invalid: :replace option but without undef: :replace
  • Now correctly raises Encoding::UndefinedConversionError matching MRI behavior

Problem

When calling:

"1ĀŽ2".encode("windows-1252", invalid: :replace, replace: "")

JRuby 10.0.2.0 threw:

NoMethodError: undefined method '[]' for nil
  encode at org/jruby/RubyString.java:6845

Expected (MRI behavior):

Encoding::UndefinedConversionError: U+0100 to WINDOWS-1252

Root Cause

In EncodingUtils.transcodeLoop(), when ecopts hash exists (due to :replace option) but doesn't contain a :fallback key, the code was setting fallbackFunc = AREF_FALLBACK with fallback = nil. When an undefined conversion was encountered, it tried to call nil.[]() which raised NoMethodError.

Fix

Added a check for !fallback.isNil() before assigning the fallback function, ensuring that the fallback is only used when explicitly provided via the :fallback option.

Test plan

  • Verified the bug is reproduced on master before the fix
  • Verified the fix resolves the issue
  • Ran existing encoding specs - no regressions (same 8 failures/4 errors as before, unrelated to this fix)

Fixes #9009

When encoding a string with `invalid: :replace` and `replace:` options but
without `undef: :replace`, JRuby was incorrectly throwing NoMethodError
instead of Encoding::UndefinedConversionError.

The bug occurred because when `ecopts` hash exists (due to `:replace` option)
but doesn't contain a `:fallback` key, the code was setting `fallbackFunc` to
`AREF_FALLBACK` with a nil `fallback` value. When an undefined conversion was
encountered, it tried to call `nil.[]()` which raised NoMethodError.

The fix adds a check for `!fallback.isNil()` before assigning the fallback
function, ensuring that the fallback is only used when explicitly provided.

Fixes jruby#9009
@khasinski khasinski force-pushed the fix-encoding-undefined-conversion-error branch from d756e3f to d66b260 Compare January 18, 2026 18:37
@headius
Copy link
Member

headius commented Jan 29, 2026

Nice thanks! I think this can go into 10.0.3.0 if @enebo approves.

@headius
Copy link
Member

headius commented Jan 29, 2026

@khasinski One small nitpick... could you see if there's any equivalent spec under spec/ruby? If it's there and tagged (spec/tags/ruby) we can remove the tag. If it's not there, you can port your code over.

This will improve ruby/spec for all impls.

@headius headius added this to the JRuby 10.0.3.0 milestone Jan 29, 2026
Move test for UndefinedConversionError behavior from JRuby-specific
test suite to shared ruby/spec. Also add spec for the basic case
of encoding without options raising UndefinedConversionError.

Related to jruby#9009
@khasinski khasinski requested a review from headius January 29, 2026 01:39
@headius
Copy link
Member

headius commented Jan 29, 2026

Great thanks! I'll check if that existing spec is currently excluded.

@headius
Copy link
Member

headius commented Jan 30, 2026

I tested your branch and did not see any additional specs pass, so I'll merge what we have here.

If you would like to work on those other failures, that would be great!

https://github.com/jruby/jruby/blob/16933595c7ff9d39a395f6e22639bf109874932d/spec/ruby/core/string/encode_spec.rb

@headius headius merged commit a721b2c into jruby:master Jan 30, 2026
77 checks passed
@khasinski khasinski deleted the fix-encoding-undefined-conversion-error branch January 30, 2026 01:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Encoding a string with undefined chars fails with NoMethodError

2 participants