Skip to content

[BUG] Data loss in cleanup_orphaned_tool_results with custom assocation #583

@bschmeck

Description

@bschmeck

Basic checks

  • I searched existing issues - this hasn't been reported
  • I can reproduce this consistently
  • This is a RubyLLM bug, not my application code

What's broken?

In cleanup_orphaned_tool_results, we ensure that our associations are properly built by comparing the tool call message's tool_calls to the foreign keys on the tool call message's tool results. The name of the foreign key column is hardcoded as :tool_call_id, but a custom association may result in a different column name.

In those cases, the call to pluck(:tool_call_id) returns the string tool_call_id column from the tool call table. Those ids will never match the expected ids plucked from the message's tool calls, which leads us to falsely believe that we have orphaned tool results. That forces us to destroy tool results that should have been preserved.

How to reproduce

Create custom associations for messages and tool calls, with custom foreign key columns:

ActiveRecord::Migration.create_table :chat_messages, force: true do |t|
  t.references :chat
  ...
  t.references :chat_tool_call
  t.timestamps
end

ActiveRecord::Migration.create_table :chat_tool_calls, force: true do |t|
  t.references :chat_message
  t.string :tool_call_id
  t.string :name
  t.json :arguments
  t.timestamps
end

class Chat::Message < ActiveRecord::Base
  acts_as_message tool_calls: :chat_tool_calls, tool_call_class: "Chat::ToolCall", tool_calls_foreign_key: "chat_message_id"
end

class Chat::ToolCall < ActiveRecord::Base
  acts_as_tool_call message: :chat_message, message_class: "Chat::Message", message_foreign_key: "chat_message_id", result: :result, result_class: "Chat::Message", result_foreign_key: "chat_tool_call_id"
end

Create a chat message, with a tool call and result, then force an error (or call cleanup_orphaned_tool_results directly)

Expected behavior

The tool call and result should be persisted in the database and associated with the chat message.

What actually happened

The tool call and result are destroyed.

Environment

Ruby 4.0
RubyLLM 1.11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions