berti92 brain dump

3 min read Original article ↗

The Danger of a Single Capital Letter: How I Almost Ruined a Redmine Instance

2026-01-26

Back to overview

I love Ruby. To be more precise, I love Ruby on Rails. It’s incredibly intuitive and allows for rapid development. But there is a catch: Ruby gives you a very sharp knife, and it’s remarkably easy to accidentally shoot yourself in the foot with it.

For years, I’ve been developing plugins and scripts for Redmine. Recently, I took on a new client for whom I host Redmine and provide custom enhancements.

The Request

The client needed a simple automation script. The logic was straightforward: every minute, the script should check a specific project for new tickets. If a ticket was created by a user with a specific email domain, it should be moved to a corresponding project. For example: "If an email comes from user@dell.com, move that issue to the Dell project."

To implement this, I added a custom field called "Customer Email Domain" to the project settings, allowing the client to map domains to their respective projects. The Implementation

I wrote a small script to run as a cron job every minute. Here is the core logic: Ruby

issues.each do |issue|
  if new_project
    # The fatal line
    Issue.update(project: new_project)
    puts "Moved Issue ##{issue.id} (#{owner_email}) to project ##{new_project.id}"
  else
    puts "No target project found for #{owner_email} (Issue ##{issue.id})"
  end
end

"Fuck"

At first glance, it looks fine, right? Wrong.

Within minutes of deploying, I realized I had made a catastrophic mistake. Instead of moving one ticket at a time, my script was moving every single ticket in the entire database to the new project. Every. Single. Minute.

The Culprit: A Single Capital Letter

The mistake lies here:

  • Wrong: Issue.update(project: new_project)
  • Right: issue.update(project: new_project)

What’s the difference?

  • issue (lowercase) refers to the specific object inside the loop. Calling .update on it changes only that one record.
  • Issue (uppercase) refers to the Class/Model itself. In Rails, calling .update on a Model without a specific ID or scope applies that change to all records in the table.

It was a tiny typo with a massive consequence. Because of that one capital letter, the script told the database: "Update all Issues and set their project to X."

The Lesson

We all make mistakes, but the difference between a "bad day" and a "career disaster" is preparation. In this case, the damage was manageable because the client was still in the early stages of onboarding. More importantly, I had automated daily backups. I was able to restore the database to its previous state and fix the mess quickly.

So, dear colleagues: Always make backups, and more importantly, test them. You never know when a single Shift-key press might try to ruin your day.