{"record":{"id":"8f892252983c37df","repo":"forem/forem","slug":"invalid-spotify-uri-or-url","errorCode":null,"errorMessage":"Invalid Spotify URI or URL.","messagePattern":"Invalid Spotify URI or URL\\.","errorType":"exception","errorClass":"StandardError","httpStatus":null,"severity":"error","filePath":"app/liquid_tags/spotify_tag.rb","lineNumber":40,"sourceCode":"    @height = TYPE_HEIGHT[@type.to_sym]\n  end\n\n  def render(_context)\n    ApplicationController.render(\n      partial: PARTIAL,\n      locals: {\n        type: @type,\n        id: @id,\n        height: @height\n      },\n    )\n  end\n\n  private\n\n  def parse_input(input)\n    match = pattern_match_for(input, REGEXP_OPTIONS)\n    raise StandardError, I18n.t(\"liquid_tags.spotify_tag.invalid_spotify_uri\") unless match\n\n    [match[:type], match[:id]]\n  end\nend\n\nLiquid::Template.register_tag(\"spotify\", SpotifyTag)\n\nUnifiedEmbed.register(SpotifyTag, regexp: SpotifyTag::REGISTRY_REGEXP)\n","sourceCodeStart":22,"sourceCodeEnd":49,"githubUrl":"https://github.com/forem/forem/blob/f354c376a7c5d1330dc40d66f150be8d1289020d/app/liquid_tags/spotify_tag.rb#L22-L49","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use the canonical share URL of a supported type: {% spotify https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC %}.","Or the URI form: {% spotify spotify:track:4uLU6hMCjMI75M1A2tKUQC %}.","Expand spotify.link short links to full URLs before embedding; keep the optional ?si= param only (other params break the match)."],"exampleFix":"// before\n{% spotify https://spotify.link/abc123 %}\n\n// after\n{% spotify https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC?si=abc-123 %}","handlingStrategy":"validation","validationCode":"SPOTIFY_URL = %r{\\Ahttps://open\\.spotify\\.com/(track|artist|playlist|album|episode|show)/\\w{,22}(\\?si=[\\w-]+)?\\z}\nSPOTIFY_URI = /\\Aspotify:(track|artist|playlist|album|episode|show):\\w{22}\\z/\nSPOTIFY_URI_LEGACY = /\\Aspotify:user:\\w+:playlist:\\w{22}\\z/\ndef spotify_embeddable?(input)\n  input = input.strip\n  input.match?(SPOTIFY_URL) || input.match?(SPOTIFY_URI) || input.match?(SPOTIFY_URI_LEGACY)\nend","typeGuard":null,"tryCatchPattern":"begin\n  Liquid::Template.parse(markdown).render\nrescue StandardError => e\n  show_editor_error(e.message)\nend","preventionTips":["Expand spotify.link short links before saving content.","Stick to the six supported types; ids are exactly 22 chars in URI form.","Only the ?si= share param is tolerated — drop all others."],"tags":["liquid","spotify","forem","url-validation","uri-format"],"backgroundTag":"liquid-tag-validation-error","analyzedSha":"f354c376a7c5d1330dc40d66f150be8d1289020d","analyzedAt":"2026-08-21T12:43:44.428Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}