{"record":{"id":"cca5f69b436c17c7","repo":"ankane/pghero","slug":"unknown-format","errorCode":null,"errorMessage":"Unknown format","messagePattern":"Unknown format","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/pghero/methods/explain.rb","lineNumber":52,"sourceCode":"      def explain_safe?\n        select_all(\"SELECT 1; SELECT 1\")\n        false\n      rescue ActiveRecord::StatementInvalid\n        true\n      end\n\n      def add_explain_option(options, name, value)\n        unless value.nil?\n          options << \"#{name}#{value ? \"\" : \" FALSE\"}\"\n        end\n      end\n\n      # important! validate format to prevent injection\n      def explain_format(format)\n        if [\"text\", \"xml\", \"json\", \"yaml\"].include?(format)\n          format.upcase\n        else\n          raise ArgumentError, \"Unknown format\"\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":34,"sourceCodeEnd":58,"githubUrl":"https://github.com/ankane/pghero/blob/7edb57986ffd36f9d64f0830c4ccc90a5eac46d6/lib/pghero/methods/explain.rb#L34-L58","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Pass one of the exact lowercase strings: \"text\", \"xml\", \"json\", \"yaml\"","Normalize symbols and case at the call site: format.to_s.downcase","Whitelist user input before passing it: %w[text xml json yaml].include?(params[:format]) or default to \"text\""],"exampleFix":"# before - symbol fails the string whitelist\ndatabase.explain(sql, format: :json)\n\n# after - exact lowercase string\ndatabase.explain(sql, format: \"json\")","handlingStrategy":"type-guard","validationCode":"format = format.to_s.downcase\nformat = \"text\" unless %w[text xml json yaml].include?(format)\ndatabase.explain(sql, format: format)","typeGuard":"def valid_explain_format?(value)\n  %w[text xml json yaml].include?(value.to_s.downcase)\nend","tryCatchPattern":null,"preventionTips":["Pass lowercase strings, not symbols, for the format keyword","Whitelist any request-supplied format before it reaches explain"],"tags":["pghero","explain","argument-validation","ruby"],"backgroundTag":"invalid-enum-value","analyzedSha":"7edb57986ffd36f9d64f0830c4ccc90a5eac46d6","analyzedAt":"2026-08-21T17:33:54.942Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}