BugMojoBugMojoBugMojo
FeaturesPricingBlogGuidesAbout
Log inGet started
BugMojoBugMojo

Bug reports that actually help fix bugs — capture, replay, share.

A product of Softech Infra.

Product

  • Features
  • Pricing
  • Get started
  • Log in

Resources

  • Blog
  • Guides
  • Compare
  • Glossary

Company

  • About
  • Contact
  • Privacy
  • Sitemap
  • Engineering
  • Playbooks
© 2026 BugMojo. All rights reserved.
AllGuidesEngineeringPlaybooksCompareGlossaryAlternativesBy roleBug tracking by framework
  1. Home
  2. Blog
  3. Bug tracking by framework
  4. Ruby on Rails 8
Bug tracking by framework

Bug tracking for Rails — session replay, console + HAR (2026)

Debug Rails Hotwire bugs — Turbo Frame "Content missing", Stimulus data-action not firing, Turbo Stream broadcasts, and Turbo 8 morphing — with rrweb replay, console, and

6 min read·Ruby
Isometric thin line-art browser rendering a Rails app with a highlighted turbo-frame panel mid-swap revealing a Content missing card and a turbo-stream WebSocket request arcing toward an IDE node, lit by a single lime glow

What Rails teams ship with BugMojo

Rails shipped its frontend as React for years, but that era is over. In the 2024 Ruby on Rails Community Survey of 2,709 developers, Stimulus (31%) overtook React (24%) as the most-used JavaScript library alongside Rails — which means the typical 2026 Rails frontend bug is a Hotwire bug, not a React bug. The failures your team now spends the most time on are a Turbo Frame that renders "Content missing", a Stimulus data-action that silently never fires, a Turbo Stream broadcast that updates the wrong element, and a Turbo 8 morph that resets scroll or JavaScript state. None of these throw a stack trace you can paste into an issue; all of them are decided by the exact DOM, console, and network state at the failure instant.

A useful bug report from a Rails-on-Hotwire app needs three things a screenshot cannot carry: the rendered DOM at the moment of the swap (did the response actually contain a <turbo-frame> with the matching id?), the captured network status (a frame that 404s fails differently from one that returns 200 with the wrong body), and the WebSocket frames for Action Cable (the literal <turbo-stream action target> payload that did or did not match an element on the page). BugMojo captures an rrweb replay, the browser console, and the full network HAR including WebSocket frames, so every one of those questions is answerable after the fact instead of "cannot reproduce".

Rails gotchas

Framework-specific failure modes engineers actually ship through. Each is hard to spot in a screenshot and obvious in a session replay.

"Content missing" means the response had no matching <turbo-frame>

Turbo extracts the <turbo-frame> with the matching id out of the response and swaps only that element. If the response omits it — a redirect to a page without the frame, an error page, or the wrong template — Turbo writes an informational "Content missing" message into the frame and dispatches a turbo:frame-missing event you can intercept. The captured DOM tells you whether the id was actually present.

turbo:frame-missing does NOT fire on a non-200 response

Per hotwired/turbo issue #670, turbo:frame-missing is not dispatched when the framed request returns a non-200 status such as a 404. So a frame that 404s fails differently from one that returns 200 with the wrong body, and any handler you wired to frame-missing simply never runs. This is exactly why the captured network status code is decisive — the visible result looks identical, the cause does not.

A data-action on a div/li silently never fires

Stimulus' default-events table maps element types to events automatically: a/button/input[type=submit] => click, form => submit, input/textarea => input, select => change, details => toggle. A descriptor like "profile#save" on a non-default element (a div, li, span) never fires because no default event exists for it — you must write the full click->profile#save descriptor. Nothing errors; the handler just doesn't run.

A capitalized Stimulus identifier drops your action params

Stimulus controller identifiers must be lowercase. When the identifier contains a capital letter, action parameters are not passed (hotwired/stimulus #561) — a class of "the handler runs but params are undefined" bug that is invisible without seeing the exact data-controller and data-action attributes in the captured DOM. The controller connects, the method fires, and the data-*-param values silently arrive empty.

Turbo 8 morphing loses state that idiomorph can't match

Turbo 8 page refreshes use the idiomorph library to mutate the existing DOM in place instead of replacing it, which normally preserves scroll and focus. State is still lost when an element's identity changes between renders so idiomorph can't pair it, when third-party widgets get re-morphed, or when a region that should be left alone is not wrapped in data-turbo-permanent. Broadcast refreshes are debounced, so only the last refresh in a burst applies.

Common Rails bugs

Real Rails bug patterns — the symptom you will see in a report and the fix that actually works.

Turbo Frame renders "Content missing" instead of swapping

Symptom: Clicking a link inside a <turbo-frame> shows a "Content missing" placeholder instead of the expected content, and the page does not navigate.

Fix: The server response did not contain a <turbo-frame> with the same id. Make the controller render a response that includes the matching frame, break out of the frame with data-turbo-frame="_top" (or target="_top"), or intercept turbo:frame-missing to follow the redirect. Check the captured network status first: if it 404s, turbo:frame-missing never fires (issue #670), so a status-based handler is the real fix.

javascriptjavascript
// Intercept the missing-frame case and follow the real location
document.addEventListener("turbo:frame-missing", (event) => {
  const { detail: { response, visit } } = event;
  event.preventDefault();
  visit(response.url);
});

Stimulus action wired to a non-default element never runs

Symptom: A button-styled <div> with data-action="menu#toggle" does nothing on click. The controller is connected; no error appears in the console.

Fix: A bare "menu#toggle" relies on a default event, and a div has none (only a/button => click, form => submit, input => input, select => change). Write the full descriptor so the event is explicit. While debugging, read the exact data-action and data-controller attributes from the captured DOM and confirm in the console that the controller connect() actually ran.

htmlhtml
<!-- ❌ no default event on a div, never fires -->
<div data-controller="menu" data-action="menu#toggle">Open</div>

<!-- ✅ explicit event descriptor -->
<div data-controller="menu" data-action="click->menu#toggle">Open</div>

Turbo Stream broadcast updates nothing (or the wrong element)

Symptom: An Action Cable broadcast fires server-side, but the page never updates — or a different element changes than intended. No navigation, no console error.

Fix: A <turbo-stream> targets an element by DOM id and no-ops silently when that id is not on the page, when the client never subscribed to the channel, or when the stream wraps the wrong partial. Inspect the WebSocket frames in the captured network log to read the literal action and target, and use the DOM replay to confirm whether the target id existed when the frame arrived.

htmlhtml
<!-- target id must exist in the live DOM or this is a silent no-op -->
<turbo-stream action="replace" target="message_42">
  <template>
    <div id="message_42">Updated body</div>
  </template>
</turbo-stream>

BugMojo vs alternatives

The honest comparison — where BugMojo wins, and where another tool might serve you better.

FeatureBugMojoTelescope / Sentry / DevTools
DOM session replay of the exact Turbo/Stimulus interaction✅ rrweb-based, shows the frame swap & morph⚠️ Sentry replay (sampled); DevTools lose it on reload
Network HAR with the frame's response status + WebSocket turbo-stream frames✅ shows 200 vs 404 and the action/target payload⚠️ server-side logs only; no client WebSocket view
Reads the exact data-controller / data-action attributes at failure✅ captured DOM, no instrumentation❌ not captured
MCP server: Claude Code / Cursor read the Rails report in the IDE✅ bug is a first-class AI assignee❌ none expose sessions to an AI agent over MCP
Always-on production error monitoring & aggregation❌ on-demand capture✅ Sentry / AppSignal / Honeybadger are more complete
Local request / query / job inspection in development❌✅ Rails Telescope-style tools (local dev)
Console + network (HAR) capture✓Partial
Zero-setup Quick CaptureNo project, no SDKAccount / SDK required
The BugMojo column is highlighted. The closing rows are BugMojo’s core wedge: rrweb session replay, MCP for AI agents, console + network capture, and zero-setup Quick Capture.
Capture your next bug in 15 seconds

BugMojo records the DOM, console, and network — then ships a one-click ticket with the full replay attached. No SDK, no setup.

Try BugMojo free

Frequently asked questions

Frequently asked questions

Sources

  1. Turbo Handbook — Frames (frame-missing behavior, target=_top scoping, eager/lazy src loading) — Hotwired (turbo.hotwired.dev, official docs) (2025)
  2. Stimulus Reference — Actions (event->controller#method descriptor, default-events-per-element table, identifier rules) — Hotwired (stimulus.hotwired.dev, official docs) (2025)
  3. 2024 Ruby on Rails Community Survey — Stimulus (31%) overtook React (24%) as the most-used JS library alongside Rails; 2,709 respondents — Ruby on Rails Community Survey / Planet Argon (2024)
  4. A happier happy path in Turbo with morphing (idiomorph, data-turbo-permanent, broadcast debounce) — 37signals Dev (Jorge Manrubia) (2023)
  5. turbo:frame-missing event not dispatched when response code is not 200 (#670) — hotwired/turbo GitHub Issues (2024)
  6. Smooth page refreshes with morphing — Turbo handbook page-refreshes (turbo-refresh-method morph) — Hotwired (turbo.hotwired.dev, official docs) (2025)
Share:

More frameworks

Pick another — each guide has its own gotchas, comparison, and fixes.

React 19
JavaScript
Vue 3.5
JavaScript
Laravel 12
PHP
Next.js 15
JavaScript
WordPress
PHP / CMS
Angular 19
TypeScript

On this page

  • What Rails teams ship with BugMojo
  • Rails gotchas
  • Common Rails bugs
  • BugMojo vs alternatives