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

  1. Restructure config/pghero.yml to the preferred format with a top-level databases: key listing each database (url: or spec:)
  2. 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)
  3. Verify the environment name: print PgHero.env (from RAILS_ENV or RACK_ENV, default "development") and confirm the file has that key
  4. 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

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


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