{"record":{"id":"b77715ae7176914e","repo":"ankane/pghero","slug":"invalid-database-id","errorCode":null,"errorMessage":"Invalid database id","messagePattern":"Invalid database id","errorType":"validation","errorClass":"PgHero::Error","httpStatus":null,"severity":"error","filePath":"lib/pghero/methods/system.rb","lineNumber":90,"sourceCode":"          data\n        else\n          raise NotEnabled, \"System stats not enabled\"\n        end\n      end\n\n      private\n\n      def gcp_stats(metric_name, duration: nil, period: nil, offset: nil, series: false)\n        # TODO DRY with RDS stats\n        duration = (duration || 1.hour).to_i\n        period = (period || 1.minute).to_i\n        offset = (offset || 0).to_i\n        end_time = Time.at(((Time.now - offset).to_f / period).ceil * period)\n        start_time = end_time - duration\n\n        # validate input since we need to interpolate below\n        raise Error, \"Invalid metric name\" unless /\\A[a-z\\/_]+\\z/i.match?(metric_name)\n        raise Error, \"Invalid database id\" unless /\\A[a-z0-9\\-:]+\\z/i.match?(gcp_database_id)\n\n        # we handle three situations:\n        # 1. google-cloud-monitoring-v3\n        # 2. google-cloud-monitoring\n        # 3. google-apis-monitoring_v3\n        begin\n          require \"google/cloud/monitoring/v3\"\n        rescue LoadError\n          require \"google/apis/monitoring_v3\"\n        end\n\n        # for situations 1 and 2\n        # Google::Cloud::Monitoring.metric_service doesn't work for situation 1\n        if defined?(Google::Cloud::Monitoring::V3)\n          client = Google::Cloud::Monitoring::V3::MetricService::Client.new\n\n          interval = Google::Cloud::Monitoring::V3::TimeInterval.new\n          interval.end_time = Google::Protobuf::Timestamp.new(seconds: end_time.to_i)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/ankane/pghero/blob/7edb57986ffd36f9d64f0830c4ccc90a5eac46d6/lib/pghero/methods/system.rb#L72-L108","documentation":"PgHero raises this from the private gcp_stats helper (lib/pghero/methods/system.rb:90) when the configured gcp_database_id fails /\\A[a-z0-9\\-:]+\\z/i. Like the metric-name check, it guards interpolation: gcp_database_id is embedded verbatim into the Cloud Monitoring filter (resource.label.database_id = \"...\") and split(\":\").first is used for the project path, so characters outside alphanumerics, hyphens, and colons are rejected before any API call. A well-formed Cloud SQL id looks like myproject:us-central1:myinstance.","triggerScenarios":"Setting gcp_database_id in config/pghero.yml to a value with dots, slashes, spaces, quotes, or the full resource path (\"projects/myproject/instances/inst\") instead of project:region:instance; then calling any system-stats method (cpu_usage, connection_stats, ...) on that database, which routes to gcp_stats.","commonSituations":"Copy-pasting the instance connection name from the GCP console in the wrong format; wrapping the YAML value in extra quotes that become part of the string; trailing whitespace from YAML indentation; using the instance's IP or DNS name instead of the database_id.","solutions":["Set gcp_database_id to the exact project:region:instance form, e.g. `gcp_database_id: myproject:us-central1:myinstance` in config/pghero.yml, with no quotes, spaces, or path prefixes.","Verify the value against the regex in console: /\\A[a-z0-9\\-:]+\\z/i.match?(PgHero.config.dig(\"databases\", \"main\", \"gcp_database_id\")) or simply check PgHero.gcp_database_id.","Restart/reload the app after editing pghero.yml so the config cache picks up the new value."],"exampleFix":"# before - config/pghero.yml\n#   gcp_database_id: projects/myproject/instances/myinstance\n# raises PgHero::Error: Invalid database id\n\n# after - project:region:instance form\n#   gcp_database_id: myproject:us-central1:myinstance\nPgHero.cpu_usage","handlingStrategy":"validation","validationCode":"id = PgHero.gcp_database_id\nraise ArgumentError, \"bad gcp_database_id\" unless id.is_a?(String) && id.match?(/\\A[a-z0-9\\-:]+\\z/i)\nPgHero.cpu_usage","typeGuard":"def valid_gcp_database_id?(id)\n  id.is_a?(String) && id.match?(/\\A[a-z0-9\\-:]+\\z/i) && id.count(\":\") == 2\nend","tryCatchPattern":"begin\n  PgHero.cpu_usage(duration: 1.hour)\nrescue PgHero::Error => e\n  raise unless e.message == \"Invalid database id\"\n  Rails.logger.error(\"Fix gcp_database_id in pghero.yml (expected project:region:instance)\")\n  {}\nend","preventionTips":["Document the project:region:instance format next to the key in pghero.yml comments.","Add a boot-time config assertion for gcp_database_id format so bad deploys fail fast.","Copy the value from `gcloud sql instances describe` connectionName-adjacent output, never from the console URL."],"tags":["pghero","gcp","cloud-sql","configuration","yaml","validation"],"backgroundTag":"invalid-configuration-value","analyzedSha":"7edb57986ffd36f9d64f0830c4ccc90a5eac46d6","analyzedAt":"2026-08-21T17:33:54.942Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}