ankane/pghero · critical · PgHero::Error
Invalid config file
Error message
Invalid config file
What it means
PgHero.file_config reads config/pghero.yml (or PGHERO_CONFIG_PATH), renders ERB and YAML.safe_loads it. The resulting hash must either contain a key for the current environment (legacy per-env format) or a top-level "databases" key (preferred format). If the file exists but has neither, PgHero raises Error "Invalid config file" - meaning the YAML parsed fine but its shape is not recognized.
Source
Thrown at lib/pghero.rb:120
def file_config
unless defined?(@file_config)
require "erb"
require "yaml"
path = config_path
config_file_exists = File.exist?(path)
config = YAML.safe_load(ERB.new(File.read(path)).result, aliases: true) if config_file_exists
config ||= {}
@file_config =
if config[env]
config[env]
elsif config["databases"] # preferred format
config
elsif config_file_exists
raise Error, "Invalid config file"
else
nil
end
end
@file_config
end
# private
def default_config
databases = {}
unless ENV["PGHERO_DATABASE_URL"]
ActiveRecord::Base.configurations.configs_for(env_name: env, include_hidden: true).each do |db|
databases[db.name] = {"spec" => db.name}
end
end
View on GitHub (pinned to 7edb57986f)
Solutions
- Restructure config/pghero.yml to the preferred format with a top-level databases: key listing each database (url: or spec:)
- If you must keep per-env format, add a key matching the current env exactly (e.g. production: with the db config nested under it)
- Verify the environment name: print PgHero.env (from RAILS_ENV or RACK_ENV, default "development") and confirm the file has that key
- Confirm PGHERO_CONFIG_PATH points at the intended file and the file parses: YAML.safe_load(File.read(path), aliases: true) in rails console
Example fix
# config/pghero.yml - before (no databases key, no matching env key)
username: admin
password: secret
# after (preferred format)
databases:
primary:
url: postgres://user:pass@localhost/mydb
username: admin
password: secret Defensive patterns
Strategy: validation
Validate before calling
# config/initializers/pghero_check.rb - fail at boot, not at first request
path = PgHero.config_path
if File.exist?(path)
require "yaml"
require "erb"
cfg = YAML.safe_load(ERB.new(File.read(path)).result, aliases: true) || {}
unless cfg["databases"] || cfg[PgHero.env]
raise "config/pghero.yml must define a top-level 'databases' key or a '#{PgHero.env}' key"
end
end Try / catch
begin
PgHero.config
rescue PgHero::Error => e
# surface config problems clearly at deploy time instead of a 500 per request
Rails.logger.fatal("pghero config invalid: #{e.message}")
raise
end Prevention
- Standardize on the databases: format for pghero.yml and assert its shape in CI
- Keep RAILS_ENV/RACK_ENV explicit in deploys so the env-key format cannot silently mismatch
- Add a boot-time or deploy-time check that loads pghero.yml and validates its keys
When it happens
Trigger: A pghero.yml containing only top-level keys like username/password with no databases: mapping; an env mismatch where the file has a development: key but RAILS_ENV/RACK_ENV is production and no databases: key exists; a file whose YAML body is effectively empty (e.g. only ERB comments), which safe_load turns into a hash without usable keys.
Common situations: Migrating from the legacy per-environment format to the databases: format and leaving the file half-written; setting PGHERO_CONFIG_PATH to the wrong file; deploying with a different RAILS_ENV than the one used locally; Docker deployments where the mounted config differs per stage.
Related errors
- Spec not found: #{config["spec"]}
- Invalid connection URL
- Unsafe statement
- Database not found: #{database_id}
- Historical query stats not enabled
AI-assisted analysis of ankane/pghero@7edb57986f (2026-08-21).
Data as JSON: /api/errors/ebb5d07db731d7f8.
Report an issue: GitHub.