Skip to content

Fix NoMethodError when Error is raised with a string argument#653

Merged
crmne merged 3 commits intocrmne:mainfrom
cgmoore120:fix/error-string-argument
Mar 6, 2026
Merged

Fix NoMethodError when Error is raised with a string argument#653
crmne merged 3 commits intocrmne:mainfrom
cgmoore120:fix/error-string-argument

Conversation

@cgmoore120
Copy link
Contributor

Summary

RubyLLM::Error.new("message") puts the string in the response parameter, then super(message || response&.body) calls .body on a String, raising NoMethodError. This fix detects a String in the first position and treats it as the message instead, keeping full backward compatibility with the two-arg ErrorMiddleware path.

Reproduction

  1. Install ruby_llm and open a console:
require 'ruby_llm'
  1. Raise an error with just a string message (as several providers already do internally):
RubyLLM::Error.new("something went wrong")
  1. Expected: An Error instance with message == "something went wrong" and response == nil

  2. Actual:

NoMethodError: undefined method `body' for an instance of String
  from lib/ruby_llm/error.rb:11:in `initialize'

This happens because the constructor signature is initialize(response = nil, message = nil) — the string lands in response, and super(message || response&.body) calls .body on it.

Existing call sites that trigger this

lib/ruby_llm/providers/bedrock/streaming.rb:49      → raise Error, "..."
lib/ruby_llm/providers/gemini/images.rb:32           → raise Error, "..."
lib/ruby_llm/providers/vertexai.rb:62                → raise Error, "..."
lib/ruby_llm/providers/anthropic/embeddings.rb:11    → raise Error "..."

The normal ErrorMiddleware path always passes both args (response, message) and is unaffected.

Test plan

  • Error.new("msg") no longer raises NoMethodError
  • Error.new("msg").message returns the string
  • Error.new("msg").response is nil
  • Two-arg path Error.new(response, "msg") still works
  • No-arg path Error.new still works
  • Subclasses (BadRequestError, etc.) inherit the fix
  • Existing ErrorMiddleware specs pass

cgmoore120 and others added 2 commits March 4, 2026 15:18
RubyLLM::Error.new("message") puts the string in the `response`
parameter, then `super(message || response&.body)` calls .body on
a String. This surfaces when errors are raised outside the normal
ErrorMiddleware path (e.g., edge cases with provider intermittent
failures).

Detect String arguments in the first position and treat them as
the message instead.
@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.51%. Comparing base (bac3f3f) to head (eb3345d).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #653      +/-   ##
==========================================
+ Coverage   81.50%   81.51%   +0.01%     
==========================================
  Files         116      116              
  Lines        5476     5479       +3     
  Branches     1430     1432       +2     
==========================================
+ Hits         4463     4466       +3     
  Misses       1013     1013              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@crmne crmne merged commit bf586f8 into crmne:main Mar 6, 2026
25 checks passed
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.

2 participants