forem/forem · error · StandardError
Invalid Stack Exchange site: {% %{tag} %{input} %}
Error message
Invalid Stack Exchange site: {% %{tag} %{input} %} What it means
Forem's {% stackexchange %} tag resolves the target site before fetching data: if the tag name is 'stackoverflow' or the input matches the stackoverflow.com post URL pattern, the site is 'stackoverflow'; otherwise the input must match one of the tag's regexps AND expose a named 'subdomain' capture group, or the tag raises 'Invalid Stack Exchange site' with the tag name and raw input interpolated. Bare numeric ids match SITE_REGEXP (?<subdomain>\b[a-zA-Z]+\b) only when letters are present, so a bare id with the stackexchange tag fails here, not at the id check.
Source
Thrown at app/liquid_tags/stackexchange_tag.rb:54
created_at: @json_content["creation_date"],
score: @json_content["score"],
comment_count: @json_content["comment_count"],
answer_count: @json_content["answer_count"],
post_type: @post_type,
post_url: @json_content["link"] || default_link,
body: @json_content["body"]
},
)
end
private
def parse_site(input)
return "stackoverflow" if tag_name == "stackoverflow" || input.match?(STACKOVERFLOW_REGEXP)
match = pattern_match_for(input, REGEXP_OPTIONS)
# rubocop:disable Layout/LineLength
raise StandardError, I18n.t("liquid_tags.stackexchange_tag.invalid_site", tag: tag_name, input: input) unless match && match_group_present?(match, "subdomain")
# rubocop:enable Layout/LineLength
match[:subdomain].downcase
end
def match_group_present?(match, group_name)
match.names.include?(group_name)
end
def get_data(input)
id = input.split.first
match = pattern_match_for(id, REGEXP_OPTIONS)
unless match && match_group_present?(match, "id")
raise StandardError, I18n.t("liquid_tags.stackexchange_tag.invalid_id", tag: tag_name, input: input)
end
url = "#{API_URL}posts/#{match[:id]}?site=#{@site}&filter=#{FILTERS['post']}" \
"&key=#{ApplicationConfig['STACK_EXCHANGE_APP_KEY']}"View on GitHub (pinned to f354c376a7)
Solutions
- With a bare id, name the site explicitly via URL or use the subdomain form: {% stackexchange https://crypto.stackexchange.com/q/12345 %}.
- For stackoverflow.com posts, use {% stackoverflow https://stackoverflow.com/q/12345 %} or the bare id with the stackoverflow tag name.
- Match the URL shape: <subdomain>.stackexchange.com/(q|a|questions)/<digits>.
Example fix
// before
{% stackexchange 12345 %}
// after
{% stackexchange https://crypto.stackexchange.com/q/12345 %} Defensive patterns
Strategy: validation
Validate before calling
SE_SITE = %r{https://(?<subdomain>\w+)\.(?:stackexchange\.com|stackoverflow\.com)/(?:q|a|questions)/\d{1,20}}
def stackexchange_site_resolvable?(input)
return true if input.match?(SE_SITE)
input.match?(STACKOVERFLOW ||= %r{https://stackoverflow\.com/(q|a|questions)/\d{1,20}}) || input =~ /\b[a-zA-Z]+/
end Try / catch
begin Liquid::Template.parse(markdown).render rescue StandardError => e show_editor_error(e.message) # interpolates tag name and raw input end
Prevention
- Never pair a bare numeric id with the generic stackexchange tag — the site is unresolvable from digits.
- For stackoverflow.com content use the stackoverflow tag name or full URL.
- Keep the URL shape <subdomain>.stackexchange.com/(q|a|questions)/<digits>.
When it happens
Trigger: {% stackexchange 12345 %} (digits contain no letters, so no subdomain group), {% stackexchange https://stackoverflow.com/questions/123 %} with a URL shape that misses STACKOVERFLOW_REGEXP (e.g. wrong path segment like /q/ without digits or /documentation/), or any non-URL, non-site string raise at app/liquid_tags/stackexchange_tag.rb:54.
Common situations: Using the generic stackexchange tag with a bare numeric post id (the tag cannot infer the site from digits alone); typos in the site subdomain; URLs from meta.* or area51 that do not fit the (?<subdomain>\w+\.)?stackexchange\.com pattern with a captured group.
Related errors
- Invalid Stack Exchange ID: {% %{tag} %{input} %}
- No LiquidTag for given #{Settings::Community.community_name}
- Invalid Gist link: %{link} Links must follow this format: ht
- Invalid GitPitch URL
- Invalid GitHub issue, pull request or comment link
AI-assisted analysis of forem/forem@f354c376a7 (2026-08-21).
Data as JSON: /api/errors/e61b150ec61bc981.
Report an issue: GitHub.