ankane/pghero · error · ArgumentError

Unknown format

Error message

Unknown format

What it means

explain(sql, format:) interpolates the format into EXPLAIN (...) FORMAT {format}, so explain_format() whitelists exactly "text", "xml", "json", "yaml" (compared as strings) to prevent SQL injection. Any other value - a symbol like :json, a different case such as "JSON", "md", or nil - raises ArgumentError "Unknown format" before any query runs.

Source

Thrown at lib/pghero/methods/explain.rb:52

      def explain_safe?
        select_all("SELECT 1; SELECT 1")
        false
      rescue ActiveRecord::StatementInvalid
        true
      end

      def add_explain_option(options, name, value)
        unless value.nil?
          options << "#{name}#{value ? "" : " FALSE"}"
        end
      end

      # important! validate format to prevent injection
      def explain_format(format)
        if ["text", "xml", "json", "yaml"].include?(format)
          format.upcase
        else
          raise ArgumentError, "Unknown format"
        end
      end
    end
  end
end

View on GitHub (pinned to 7edb57986f)

Solutions

  1. Pass one of the exact lowercase strings: "text", "xml", "json", "yaml"
  2. Normalize symbols and case at the call site: format.to_s.downcase
  3. Whitelist user input before passing it: %w[text xml json yaml].include?(params[:format]) or default to "text"

Example fix

# before - symbol fails the string whitelist
database.explain(sql, format: :json)

# after - exact lowercase string
database.explain(sql, format: "json")
Defensive patterns

Strategy: type-guard

Validate before calling

format = format.to_s.downcase
format = "text" unless %w[text xml json yaml].include?(format)
database.explain(sql, format: format)

Type guard

def valid_explain_format?(value)
  %w[text xml json yaml].include?(value.to_s.downcase)
end

Prevention

When it happens

Trigger: database.explain(sql, format: :json) - the symbol fails the string-array include?; format: "markdown"; format: nil passed explicitly; format forwarded from controller params (params[:format]) without whitelisting - note Rails reserves params[:format] for respond_to, which makes this collision common.

Common situations: Ruby habit of passing symbols for enum-like arguments; building an API around explain that accepts a user-supplied format; mixing up this whitelist with EXPLAIN ANALYZE options.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of ankane/pghero@7edb57986f (2026-08-21). Data as JSON: /api/errors/cca5f69b436c17c7. Report an issue: GitHub.