{"record":{"id":"3463e4416f7df74c","repo":"instructure/canvas-lms","slug":"invalid-uri-in-pv5-config-e-message","errorCode":null,"errorMessage":"Invalid URI in pv5 config: #{e.message}","messagePattern":"Invalid URI in pv5 config: #(.+?)","errorType":"exception","errorClass":"Common::ConfigurationError","httpStatus":null,"severity":"error","filePath":"app/services/page_views/configuration.rb","lineNumber":35,"sourceCode":"# You should have received a copy of the GNU Affero General Public License along\n# with this program. If not, see <http://www.gnu.org/licenses/>.\n\nmodule PageViews\n  class Configuration\n    attr_reader :uri\n\n    def self.configured?\n      ConfigFile.load(\"pv5\").present?\n    end\n\n    def initialize(region: nil)\n      config = ConfigFile.load(\"pv5\")\n      raise Common::ConfigurationError, \"PV5 is not configured for this environment\" unless config.present?\n\n      regional_config = get_regional_config(config, region) || {}\n      @uri = URI.parse(regional_config[\"uri\"] || config[\"uri\"])\n    rescue URI::InvalidURIError => e\n      raise Common::ConfigurationError, \"Invalid URI in pv5 config: #{e.message}\"\n    end\n\n    private\n\n    def get_regional_config(config, region)\n      return unless config[\"regions\"].is_a?(Hash)\n\n      regional_config = config[\"regions\"][region]\n      return unless regional_config.is_a?(Hash)\n\n      regional_config\n    end\n  end\nend\n","sourceCodeStart":17,"sourceCodeEnd":50,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/page_views/configuration.rb#L17-L50","documentation":"After loading the pv5 config (optionally selecting a regional override via get_regional_config), PageViews::Configuration parses the 'uri' value with URI.parse. A URI::InvalidURIError is rescued and re-raised as Common::ConfigurationError, 'Invalid URI in pv5 config: <detail>', because the configured page-view endpoint is malformed.","triggerScenarios":"pv5 config (top-level or regional, config['regions'][region]) contains a 'uri' value that URI.parse rejects — e.g. contains spaces or unescaped characters, is a template with unexpanded placeholders, or has protocol/control characters.","commonSituations":"Copy-pasted endpoint with trailing whitespace or quotes; uninterpolated ERB/placeholder like http://${HOST}; regional config entry with a bad or empty uri overriding a valid default; hand-edited config store values.","solutions":["Fix the 'uri' value in the pv5 config (top-level or the relevant regions entry) to a well-formed absolute URL.","Run URI.parse(uri) locally against the configured value to reproduce and pinpoint the invalid characters.","Check the regional config under config['regions'][region] — a bad regional uri takes precedence over the valid default.","Validate config at deploy time (URI.parse) so bad values never reach runtime."],"exampleFix":"# before (config/page_views.yml)\nproduction:\n  uri: https://pageviews.example .com/events\n# after\nproduction:\n  uri: https://pageviews.example.com/events","handlingStrategy":"validation","validationCode":"uri = config.dig('regions', region, 'uri') || config['uri']\nURI.parse(uri.to_s) # raises URI::InvalidURIError early if malformed","typeGuard":null,"tryCatchPattern":"begin\n  PageViews::Configuration.new(region: region)\nrescue Common::ConfigurationError => e\n  Rails.logger.error(e.message)\n  alert_on_bad_pv5_config\nend","preventionTips":["Validate pv5 uri values with URI.parse at config load/deploy time","Avoid placeholders or uninterpolated templates in config uris","Audit regional overrides under config['regions'] for bad uris","Trim whitespace/quotes when entering endpoint values into config stores"],"tags":["ruby","configuration","url","page-views"],"backgroundTag":"invalid-url","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}