Repository navigation
fix(bot): pick closest-duration soundcloud fallback match - #2049
Conversation
findMatchingSoundCloudResult took the first result in SoundCloud's own search-relevance order to pass a loose title/duration threshold. That order is not a quality ranking, so sped-up edits, extended mixes, and remixes could satisfy the threshold and get played instead of the original recording. Now filters to all qualifying candidates and picks the closest duration match. Found investigating a reported "audio not good in some moments" complaint — full root-cause chain in #2048.
|
Failed to generate code suggestions for PR |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe SoundCloud matcher now evaluates all qualifying results and selects the closest duration when track duration is available. Tests cover closest-duration selection and fallback to a candidate without duration metadata. ChangesSoundCloud matching
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change selects the closest-duration qualifying SoundCloud result while preserving existing fallback behavior. No actionable merge-blocking risk remains after normal checks and review. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Graphify review — findings
Changes findMatchingSoundCloudResult to pick the duration-closest candidate rather than the first title match, filtering all qualifying results and reducing by smallest duration delta. Preserves fallback to the first candidate when no duration is available or the track duration can't be parsed. Adds spec coverage for the closest-match tie-break and the no-duration fallback.
No blocking issues surfaced.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 12 functions depend on the 11 functions this change touches.
Health — this change adds coupling hotspots:
- new:
createResilientStream()— 2 callers, 12 callees
Verification — 12 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 12 function(s) in the blast radius were not formally verified this run
· 1 more finding(s) on lines outside this diff (see the check run).
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
The duration reduce always promoted any duration-bearing candidate over a duration-less one, even when the duration-less candidate had a stronger (or exact) title match. Now ranks by title-match score first and only breaks ties on duration closeness, so an exact-title duration-less candidate correctly beats a looser-title near-duration match. Covers the mixed duration-bearing/duration-less reduce branches that the prior tests never exercised.
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.
Graphify review — findings
Replaces the first-match selection in findMatchingSoundCloudResult with a scored candidate reduction that ranks by title-match score first, then by duration closeness as a tiebreaker, treating missing duration data as neutral. Adds spec coverage for the new preference ordering (closest duration among multiple candidates, exact title over looser duration matches, and duration-less fallbacks).
Worth a look
- Result ordering contract changed when duration is supplied —
packages/bot/src/handlers/player/soundcloudMatcher.ts:97· Escalate · medium- agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 12 functions depend on the 11 functions this change touches.
Health — this change adds coupling hotspots:
- new:
createResilientStream()— 2 callers, 12 callees
Verification — 12 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 12 function(s) in the blast radius were not formally verified this run
· 1 more finding(s) on lines outside this diff (see the check run).
|
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: AI evaluation unavailable; defaulting to comment-only for safety.
Re-trigger cubic
🤖 I have created a release *beep* *boop* --- <details><summary>2.39.6</summary> ## [2.39.6](v2.39.5...v2.39.6) (2026-08-22) ### Bug Fixes * **bot:** drop the audio-features scoring path, spotify returns 403 ([#2074](#2074)) ([11891bf](11891bf)) * **bot:** drop the autoplay arm that calls a removed spotify endpoint ([#2071](#2071)) ([682a795](682a795)) * **bot:** fall back past a dead spotify arm in /artist ([#2052](#2052)) ([45dc998](45dc998)) * **bot:** make three silent /play failures observable ([#2062](#2062)) ([e6b2810](e6b2810)) * **bot:** pick closest-duration soundcloud fallback match ([#2049](#2049)) ([738efb8](738efb8)) * **bot:** report a dead autoplay replenish at error level ([#2063](#2063)) ([2c5962e](2c5962e)) * **bot:** report spotify extractor health instead of failing silently ([#2060](#2060)) ([ddaa287](ddaa287)) * **bot:** rerank search results toward exact artist/title match ([#2045](#2045)) ([0c719d5](0c719d5)) * **bot:** resolve /album text queries to an album url ([#2053](#2053)) ([4498299](4498299)) * **bot:** restore youtube-dl-exec, discord-player-youtubei needs it undeclared ([#2040](#2040)) ([c75475b](c75475b)) * **bot:** stop reporting an outage when the fallbacks found nothing ([#2069](#2069)) ([37412e2](37412e2)) * **bot:** surface dead last.fm env session key to sentry ([#2047](#2047)) ([3c97291](3c97291)) * **bot:** update a case reason through the service layer ([#2066](#2066)) ([187d783](187d783)) * **bot:** use metadata setter instead of direct property assignment ([#2042](#2042)) ([740d53e](740d53e)) ### Performance Improvements * **bot:** cut yt-dlp timeout from 15s to 6s ([#2044](#2044)) ([39e9e3c](39e9e3c)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).



What
Part of the investigation in #2048 ("audio not good in some moments").
findMatchingSoundCloudResult(packages/bot/src/handlers/player/soundcloudMatcher.ts) usedresults.find(...)— the first SoundCloud search result to pass a loose ≥75%-title-token-overlap + ±30s-duration filter. SoundCloud's search-relevance order is not a quality ranking, so a sped-up edit, "8D audio" remix, or extended mix can satisfy that threshold and get picked over the actual original — this is one of two identified contributors to the reported audio-quality complaint (the other, larger contributor was a contaminated cookies file, already fixed same day).Fix
Filters to all qualifying candidates first, then picks the one whose duration is closest to the source track — the cheapest available signal (given
SoundCloudSearchResultonly carriesname/url/durationInSec) that a candidate is the unaltered original rather than an altered edit.Test plan
npx jest soundcloudMatcher.spec.ts— added 2 tests: closest-duration wins among multiple qualifying candidates even when ranked second by SoundCloud; falls back correctly when only one candidate has no duration data at allnpm run type:check --workspace=@lucky/botNot in scope here
Whether to also request an explicit stream
qualitytier fromplaydl.stream()/playdl.search()— flagged as an open follow-up in #2048, needs verifying play-dl's actual default behavior first rather than guessing.Summary by cubic
Ranks SoundCloud fallback matches by title score before duration closeness to avoid remixes/edits winning. Previously we returned the first result passing ≥75% title-token overlap and ±30s duration; now we choose among all qualifiers, prefer the higher title score, and break ties on smallest duration difference.
packages/bot/src/handlers/player/soundcloudMatcher.ts; adds tests covering closest-duration selection, duration-less ordering, and title-priority; no API or config changes.Written for commit e8bdb3b. Summary will update on new commits.
Summary by CodeRabbit