ankane/pghero · error · PgHero::Error

User not found: #{user}

Error message

User not found: #{user}

What it means

reset_query_stats(user:) scopes the reset to queries run by one role. The role name is resolved to its oid via SELECT usesysid FROM pg_user WHERE usename = :user before calling pg_stat_statements_reset; an unknown role raises Error "User not found: {user}". On some managed/locked-down Postgres instances pg_user is restricted, which can also make a valid role invisible.

Source

Thrown at lib/pghero/methods/query_stats.rb:100

      def enable_query_stats
        execute("CREATE EXTENSION IF NOT EXISTS pg_stat_statements")
        true
      end

      def disable_query_stats
        execute("DROP EXTENSION IF EXISTS pg_stat_statements")
        true
      end

      def reset_query_stats(user: nil, query_hash: nil, raise_errors: false)
        database = database_name
        database_id = select_one("SELECT oid FROM pg_database WHERE datname = :database", {database: database})
        raise Error, "Database not found: #{database}" unless database_id

        if user
          user_id = select_one("SELECT usesysid FROM pg_user WHERE usename = :user", {user: user})
          raise Error, "User not found: #{user}" unless user_id
        else
          user_id = 0
        end

        if query_hash
          query_id = query_hash.to_i
          # may not be needed
          # but not intuitive that all query hashes are reset with 0
          raise Error, "Invalid query hash: #{query_hash}" if query_id == 0
        else
          query_id = 0
        end

        binds = {user_id: user_id, database_id: database_id, query_id: query_id}
        # use execute to prevent "unknown OID 2278" warning
        execute("SELECT pg_stat_statements_reset(:user_id, :database_id, :query_id)", binds)
        true
      rescue ActiveRecord::StatementInvalid => e

View on GitHub (pinned to 7edb57986f)

Solutions

  1. Verify the role exists as the server sees it: SELECT usename FROM pg_user WHERE usename = 'name' - or list roles with \du in psql
  2. Use the exact rolname shown in the query stats "user" column on the pghero Queries page
  3. Drop the user: argument to reset stats for the whole database instead of one role
  4. If pg_user appears empty, connect with a role that has sufficient privileges to read the system catalog
Defensive patterns

Strategy: validation

Validate before calling

user_id = database.select_one("SELECT usesysid FROM pg_user WHERE usename = :u", {u: user})
database.reset_query_stats(user: user) if user_id

Prevention

When it happens

Trigger: database.reset_query_stats(user: "app_usr") where the role is misspelled or does not exist; the role was renamed or dropped after the stats were captured; connecting with a low-privilege role that cannot see other roles in pg_user on a managed service.

Common situations: Resetting stats per-user from a script with environment-specific role names; copy-pasting a role from another environment (staging vs production); managed Postgres (some hosted offerings) restricting system catalog visibility.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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