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 => eView on GitHub (pinned to 7edb57986f)
Solutions
- Verify the role exists as the server sees it: SELECT usename FROM pg_user WHERE usename = 'name' - or list roles with \du in psql
- Use the exact rolname shown in the query stats "user" column on the pghero Queries page
- Drop the user: argument to reset stats for the whole database instead of one role
- 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
- Take role names from the pghero Queries page 'user' column or \du output, not from memory
- Check pg_user visibility with the connecting role on managed Postgres before scripting per-user resets
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
- Invalid query hash: #{query_hash}
- Invalid sort
- Database not found: #{database}
- Query hash stats not enabled
- Query stats not enabled
AI-assisted analysis of ankane/pghero@7edb57986f (2026-08-21).
Data as JSON: /api/errors/31b2b489047bafdb.
Report an issue: GitHub.