yegor256/0rsk

`NoMethodError` thrown due to `nil` return on unknown chat or login in `Rsk::Telechats` methods

Open

#266 opened on May 11, 2026

View on GitHub
 (2 comments) (0 reactions) (0 assignees)Ruby (6 forks)github user discovery
buggood-titlehelp wanted

Repository metrics

Stars
 (24 stars)
PR merge metrics
 (PR metrics pending)

Description

What happens

Three methods in objects/telechats.rb index the result of a single-row SELECT without checking whether the query returned any rows:

def login_of(id)
  @pgsql.exec('SELECT login FROM telechat WHERE id = $1', [id])[0]['login']
end

def chat_of(login)
  @pgsql.exec('SELECT id FROM telechat WHERE login = $1', [login])[0]['id'].to_i
end

def diff?(chat, msg)
  @pgsql.exec('SELECT recent FROM telechat WHERE id = $1', [chat])[0]['recent'] != msg
end

When the telechat row does not exist for the given key (e.g., an inbound Telegram update from a chat id that is not wired, or a stale id whose row was deleted between two notifier ticks), exec returns an empty PG::Result. Indexing [0] then returns nil, and nil['login'] / nil['id'] / nil['recent'] raises NoMethodError: undefined method '[]' for nil.

This is the same defect family as the recently-accepted issue #264 (race in notify_all), and the same family as the six accepted bugs in zerocracy/judges-action#1357-#1362: unguarded single-row SELECTs.

What should happen

Validate the result set before indexing, and raise a friendly error consistent with the rest of the codebase. For example:

def login_of(id)
  row = @pgsql.exec('SELECT login FROM telechat WHERE id = $1', [id]).first
  raise Rsk::Urror, "Telegram chat #{id} is not wired" if row.nil?
  row['login']
end

Apply the same pattern to chat_of and diff?. Result: a missing or stale telechat row produces a deterministic Rsk::Urror rather than a raw NoMethodError, and the Telegram notification daemon can recover instead of crashing the worker.

Contributor guide