forem/forem · error · StandardError

Invalid Twitter Timeline URL

Error message

Invalid Twitter Timeline URL

What it means

TwitterTimelineTag validates input against the strictly anchored URL_REGEXP: https scheme, twitter.com host, an alphanumeric-only handle, the literal /timelines/ path, and a numeric timeline id, with nothing before or after. Any mismatch raises StandardError 'Invalid Twitter Timeline URL'.

Source

Thrown at app/liquid_tags/twitter_timeline_tag.rb:44

        href: @href
      },
    )
  end

  private

  def parse_link(link)
    href = ActionController::Base.helpers.strip_tags(link).strip
    raise_error unless valid_link?(href)
    href
  end

  def valid_link?(link)
    link.match?(URL_REGEXP)
  end

  def raise_error
    raise StandardError, I18n.t("liquid_tags.twitter_timeline_tag.invalid_url")
  end
end

Liquid::Template.register_tag("twitter_timeline", TwitterTimelineTag)

UnifiedEmbed.register(TwitterTimelineTag, regexp: TwitterTimelineTag::REGISTRY_REGEXP)

View on GitHub (pinned to f354c376a7)

Solutions

  1. Use the exact form https://twitter.com/<handle>/timelines/<numeric_id>
  2. Rewrite x.com hosts back to twitter.com before embedding
  3. Strip query strings, fragments, and trailing slashes from the URL
  4. If handles with underscores must work, extend the character class in both URL_REGEXP and REGISTRY_REGEXP ([a-zA-Z0-9_]) in your fork and add specs

Example fix

# before
{% twitter_timeline https://x.com/dev_rel/timelines/1234567890?s=20 %} # wrong host + query string

# after
{% twitter_timeline https://twitter.com/dev_rel/timelines/1234567890 %}
Defensive patterns

Strategy: validation

Validate before calling

href = input.strip
raise ArgumentError, "bad timeline URL" unless href.match?(TwitterTimelineTag::URL_REGEXP)

Type guard

def valid_timeline_url?(url)
  url.match?(TwitterTimelineTag::URL_REGEXP) # anchored: exact twitter.com/<handle>/timelines/<id> shape
end

Try / catch

begin
  Liquid::Template.parse("{% twitter_timeline #{href} %}")
rescue StandardError => e
  raise unless e.message == I18n.t("liquid_tags.twitter_timeline_tag.invalid_url")
  # normalize: rewrite x.com -> twitter.com, strip params, retry once
end

Prevention

When it happens

Trigger: Using an x.com timeline URL; a handle containing '_' (only [a-zA-Z0-9] is allowed); a trailing slash, query string, or fragment after the id; an http:// URL; a plain profile URL like https://twitter.com/username.

Common situations: Twitter's rebrand making x.com the host people copy from; underscores in handles (very common); share URLs appending tracking params (?s=20) that break the end anchor.

Related errors


AI-assisted analysis of forem/forem@f354c376a7 (2026-08-21). Data as JSON: /api/errors/730d25dfd0be6a87. Report an issue: GitHub.