forem/forem · error · StandardError

Invalid Spotify URI or URL.

Error message

Invalid Spotify URI or URL.

What it means

Forem's {% spotify %} tag accepts three shapes: an open.spotify.com URL (type track/artist/playlist/album/episode/show, id up to 22 word chars, optional ?si= share param), a spotify:<type>:<22-char id> URI, or the legacy spotify:user:<user>:playlist:<22-char id> URI. parse_input raises when none match after tag-stripping.

Source

Thrown at app/liquid_tags/spotify_tag.rb:40

    @height = TYPE_HEIGHT[@type.to_sym]
  end

  def render(_context)
    ApplicationController.render(
      partial: PARTIAL,
      locals: {
        type: @type,
        id: @id,
        height: @height
      },
    )
  end

  private

  def parse_input(input)
    match = pattern_match_for(input, REGEXP_OPTIONS)
    raise StandardError, I18n.t("liquid_tags.spotify_tag.invalid_spotify_uri") unless match

    [match[:type], match[:id]]
  end
end

Liquid::Template.register_tag("spotify", SpotifyTag)

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

View on GitHub (pinned to f354c376a7)

Solutions

  1. Use the canonical share URL of a supported type: {% spotify https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC %}.
  2. Or the URI form: {% spotify spotify:track:4uLU6hMCjMI75M1A2tKUQC %}.
  3. Expand spotify.link short links to full URLs before embedding; keep the optional ?si= param only (other params break the match).

Example fix

// before
{% spotify https://spotify.link/abc123 %}

// after
{% spotify https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC?si=abc-123 %}
Defensive patterns

Strategy: validation

Validate before calling

SPOTIFY_URL = %r{\Ahttps://open\.spotify\.com/(track|artist|playlist|album|episode|show)/\w{,22}(\?si=[\w-]+)?\z}
SPOTIFY_URI = /\Aspotify:(track|artist|playlist|album|episode|show):\w{22}\z/
SPOTIFY_URI_LEGACY = /\Aspotify:user:\w+:playlist:\w{22}\z/
def spotify_embeddable?(input)
  input = input.strip
  input.match?(SPOTIFY_URL) || input.match?(SPOTIFY_URI) || input.match?(SPOTIFY_URI_LEGACY)
end

Try / catch

begin
  Liquid::Template.parse(markdown).render
rescue StandardError => e
  show_editor_error(e.message)
end

Prevention

When it happens

Trigger: The new spotify.link/ short links, embed.spotify.com URLs, http (not https) open.spotify.com links (the URL regexp is https? but requires open.spotify.com host), missing type segment (bare https://open.spotify.com/id), a URI type outside the six allowed (e.g. spotify:user:), or URIs whose id is not exactly 22 word chars raise at app/liquid_tags/spotify_tag.rb:40.

Common situations: Copying the 'Spotify code' or share-sheet short link; regional/international host variants; podcast vs music type confusion (episode/show for podcasts, track for songs); ids from Spotify's newer formats differing in length.

Related errors


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