basecamp/fizzy · error · ActionController::RoutingError
Not Found
Error message
Not Found
What it means
Public board pages run through Public::BaseController, which resolves the board via Board.find_by_published_key and then calls ensure_board_accessible. That guard raises ActionController::RoutingError ("Not Found") whenever the board's owning account is cancelled, so Rails renders an HTTP 404. This is a deliberate gate that hides published boards of cancelled accounts instead of leaking that they exist.
Source
Thrown at app/controllers/public/base_controller.rb:23
before_action :ensure_board_accessible
layout "public"
private
def set_board
@board = Board.find_by_published_key(params[:board_id] || params[:id])
end
def set_card
@card = @board.cards.published.find_by!(number: params[:id]) if params[:board_id] && params[:id]
end
def set_public_cache_expiration
expires_in 30.seconds, public: true
end
def ensure_board_accessible
raise ActionController::RoutingError, "Not Found" if @board&.account&.cancelled?
end
end
View on GitHub (pinned to 7aabe74580)
Solutions
- Check the account state in console/admin (account.reload.cancelled?) and reactivate the subscription if the board should stay publicly visible.
- Confirm the link uses the current publication key (board.publication.key) — republishing a board rotates it, and old keys return 404.
- If you own the app, add rescue_from ActionController::RoutingError in Public::BaseController to render a branded 404 page instead of the default.
- When cancelling an account, purge/expiry-tag the public board caches so stale rendered pages disappear immediately.
Example fix
// before link_to "Public board", published_board_url(board) // after (don't advertise links that will 404) link_to "Public board", published_board_url(board) if board.publication.present? && !board.account.cancelled?
Defensive patterns
Strategy: validation
Validate before calling
# before rendering or sharing a public board link board = Board.find_by_published_key(key) return head :not_found if board.nil? || board.account&.cancelled?
Type guard
def public_board_available?(board) board.present? && board.publication.present? && board.account.present? && !board.account.cancelled? end
Try / catch
# only if you need a branded page instead of Rails' default 404
class Public::BaseController < ApplicationController
rescue_from ActionController::RoutingError, with: :render_public_404
private
def render_public_404
render 'public/errors/not_found', status: :not_found
end
end Prevention
- Surface account cancellation state in admin UIs so support knows why public links die.
- When an account transitions to cancelled, purge the 30-second public board caches immediately.
- Regenerate and redistribute publication links after republishing — keys rotate.
When it happens
Trigger: GET /public/boards/:publication_key, /public/boards/:publication_key/cards/:number, or the column/stream/closed/not_now sub-pages (all under the /{account_id} URL prefix on this multi-tenant app) where board.account.cancelled? is true. Every controller inheriting Public::BaseController (boards, cards, columns, streams, closeds, not_nows) hits this before_action after set_board.
Common situations: A shared public board link that worked yesterday starts returning 404 after the account's subscription lapsed or the account was closed. Stakeholders report the link as broken. Also: the 30-second public cache (expires_in 30.seconds, public: true) can serve a stale page briefly after cancellation, confusing debugging.
AI-assisted analysis of basecamp/fizzy@7aabe74580 (2026-08-21).
Data as JSON: /api/errors/5d737be1d45b8dd2.
Report an issue: GitHub.