Skip to content

fix(core): retry bpm-detective import after transient failure#2736

Open
santhiprakash wants to merge 1 commit into
heygen-com:mainfrom
santhiprakash:fix/beat-detection-retry
Open

fix(core): retry bpm-detective import after transient failure#2736
santhiprakash wants to merge 1 commit into
heygen-com:mainfrom
santhiprakash:fix/beat-detection-retry

Conversation

@santhiprakash

@santhiprakash santhiprakash commented Jul 22, 2026

Copy link
Copy Markdown

Problem

beatDetection.ts imported bpm-detective via dynamic import() and the failure was cached. If the first attempt failed due to a transient build/install issue, the module never loaded again in the same process.

Triage / Root cause

Node/V8 caches failed dynamic imports, so await import('bpm-detective') on a broken first attempt would keep rejecting without re-reading from disk.

Fix

  • Catch the initial import failure and clear the require/import cache entry for bpm-detective before retrying.
  • Refactor the import logic into a dedicated helper to keep analyzeAudio readable.
  • Add a regression test in packages/core/src/beats/beatDetection.test.ts.

Verification

  • bun test packages/core/src/beats/beatDetection.test.ts passed.
  • bunx oxlint and bunx oxfmt --check passed on changed files.

Notes / Risks

Only affects the first import attempt in a long-running process; subsequent uses are still cached on success.

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on James's go. Verified the bug + fix:

The cached-promise-never-reset bug is real — on a transient import("bpm-detective") failure the old code's .catch(() => null) left bpmDetectivePromise as a resolved-to-null promise that was never cleared, so if (!bpmDetectivePromise) stayed false and every later analyzeMusicFromBuffer silently skipped BPM detection for the rest of the session (breaking music-reactive animations / beat guides with no error).

The fix resets bpmDetectivePromise = null in the failure handler so the next call retries the import, caches only the default production import (custom loaders bypass the cache → unit-testable), and correctly distinguishes a transient import failure (reset + retry) from a successful-but-empty module (cached null, since retrying wouldn't help). Tests cover the retry-after-transient-failure path plus the default-export / module-object fallbacks. CI green.

— Rames

@jrusso1020

Copy link
Copy Markdown
Collaborator

Thanks for this — the fix looks good and CI is green, so it's approved. One thing is blocking the merge though: main requires signed commits, and the commit here (4f1c9b5) is currently unsigned (Unverified).

To unblock, sign the commit and force-push:

git commit --amend -S --no-edit
git push --force-with-lease

That needs commit signing configured (a GPG or SSH signing key + git config commit.gpgsign true). If the branch has more than one commit, sign them all (e.g. git rebase --exec 'git commit --amend -S --no-edit' <base>). Setup docs: https://docs.github.com/authentication/managing-commit-signature-verification

Once the commit shows as Verified, this is good to merge.

@santhiprakash
santhiprakash force-pushed the fix/beat-detection-retry branch from 4f1c9b5 to 3a5d8c0 Compare July 23, 2026 04:17
loadBpmDetective cached the promise returned by dynamic import even when
that import rejected. A transient failure (network hiccup, bundler issue,
missing module at first access) was therefore cached as null for the rest
of the session, silently disabling BPM detection.

- Reset the cached promise on import failure so the next call retries.
- Only cache the default production import; custom loaders bypass the cache.
- Make loadBpmDetective testable by accepting an optional importFn.
- Add regression tests for failure/retry and module/default resolution.
@santhiprakash
santhiprakash force-pushed the fix/beat-detection-retry branch from 3a5d8c0 to 920b0e3 Compare July 23, 2026 04:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants