we-promise/sure · warning
Invalid institution URL for <%= class_name %> account #{prov
Error message
Invalid institution URL for <%= class_name %> account #{provider_account.id}: #{url} What it means
In the generated provider adapter, institution_domain reads institution_metadata and, when the "domain" key is blank but "url" is present, tries URI.parse(url).host to derive the domain (stripping a leading www.). URI::InvalidURIError is rescued with this warning, leaving domain nil, which only degrades institution logo/website lookups. This is a template file — the warning text literally contains <%= class_name %> until the generator renders it.
Source
Thrown at lib/generators/provider/family/templates/adapter.rb.tt:100
<% if investment_provider? -%>
def can_delete_holdings?
false
end
<% end -%>
def institution_domain
metadata = provider_account.institution_metadata
return nil unless metadata.present?
domain = metadata["domain"]
url = metadata["url"]
# Derive domain from URL if missing
if domain.blank? && url.present?
begin
domain = URI.parse(url).host&.gsub(/^www\./, "")
rescue URI::InvalidURIError
Rails.logger.warn("Invalid institution URL for <%= class_name %> account #{provider_account.id}: #{url}")
end
end
domain
end
def institution_name
metadata = provider_account.institution_metadata
return nil unless metadata.present?
metadata["name"] || item&.institution_name
end
def institution_url
metadata = provider_account.institution_metadata
return nil unless metadata.present?
metadata["url"] || item&.institution_urlView on GitHub (pinned to e69894adb9)
Solutions
- Inspect provider_account.institution_metadata to see the exact url value that failed to parse
- Prefer populating the "domain" key in institution_metadata directly (in the generated extract_institution_metadata) so URL parsing is never needed
- Harden the generated adapter: rescue and retry with a cleaned string, or fall back to a regex host extraction
- Accept nil domain when the institution has no usable website
Example fix
# generated adapter - before
begin
domain = URI.parse(url).host&.gsub(/^www\./, "")
rescue URI::InvalidURIError
Rails.logger.warn("Invalid institution URL for #{provider_account.id}: #{url}")
end
# after
begin
domain = URI.parse(url.to_s.strip).host&.gsub(/^www\./, "")
domain ||= url.to_s[/\b(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}\b/i]
rescue URI::InvalidURIError
domain = url.to_s[/\b(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}\b/i]
Rails.logger.warn("Invalid institution URL for #{provider_account.id}: #{url}") if domain.nil?
end Defensive patterns
Strategy: try-catch
Validate before calling
# Cheap pre-check before URI.parse in the generated adapter
def parseable_url?(url)
url.is_a?(String) && url.strip.match?(%r{\Ahttps?://\S+\z})
end
domain = parseable_url?(url) ? URI.parse(url.strip).host&.gsub(/^www\./, "") : nil Type guard
def plausible_url?(value)
value.is_a?(String) && value.strip.match?(%r{\Ahttps?://[\w.-]+\.[a-z]{2,}(?:/\S*)?\z}i)
end Try / catch
begin
domain = URI.parse(url.to_s.strip).host&.gsub(/^www\./, "")
rescue URI::InvalidURIError => e
Rails.logger.warn("Invalid institution URL for #{provider_account.id}: #{url}")
domain = nil # explicit degradation, logo lookup simply skipped
end Prevention
- Store institution domain directly in metadata when the provider offers it, so URL parsing is a last resort
- Sanitize free-text institution fields (strip, scheme-check) before persisting them as url
- Add specs with pathological urls (spaces, 'N/A', no scheme) for generated adapters
When it happens
Trigger: institution_metadata["url"] is a malformed URI that raises URI::InvalidURIError: strings with spaces ("http://my bank.com"), missing scheme with bad characters ("mybank com"), placeholder text ("Not Available"), or control characters. Note: URI.parse("mybank.com") does not raise (host is nil), so the warning fires only for genuinely unparseable strings.
Common situations: Aggregator institution metadata containing display text instead of URLs; manually curated/free-text institution fields; providers that fill the url slot with a null-like sentinel ("N/A", "-"); encoding issues in copied URLs.
Related errors
- Invalid currency code '#{currency_value}' for <%= class_name
- <%= class_name %>Account::ActivitiesProcessor - Unmapped act
- <%= class_name %>ConnectionCleanupJob - Failed: #{e.class} -
- Invalid currency code '#{currency_value}' for <%= class_name
- Unexpected response format from search endpoint
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/f16399187249ffe3.
Report an issue: GitHub.