Skip to content

fix(bot): approve @discordjs/opus install script — P0 music playback outage - #1757

Merged
LucasSantana-Dev merged 3 commits into
mainfrom
fix/discordjs-opus-install-script-blocked
Jul 10, 2026
Merged

LucasSantana-Dev merged 3 commits into
mainfrom
fix/discordjs-opus-install-script-blocked

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Jul 10, 2026 •

Copy link
Copy Markdown
Owner

Incident

User reported "music not playing" + "why is Spotify not working" — investigated live prod logs (lucky-bot, guild Criativaria).

Root cause

npm 12's native install-scripts allowlist feature (npm was bumped to 12.0.0 as part of the Docker toolchain fix in #1310) silently blocks lifecycle scripts for packages not explicitly approved. @discordjs/opus's install script (node-pre-gyp install --fallback-to-build, which compiles the native Opus encoder) was never approved, so it silently no-op'd during every npm ci --omit=dev in the deps-production Docker stage — despite that stage having the full C toolchain (build-base python3-dev opus-dev) installed specifically to let this compile.

Confirmed on the running container:

$ docker exec lucky-bot find node_modules/@discordjs/opus -name '*.node'
(no output)

Impact

Total playback outage, all sources. Every /play attempt — YouTube, Spotify-matched-YouTube, SoundCloud — successfully resolves a stream, then fails identically at createAudioResource → OpusEncoder → OpusStream → loadModule because no opus native binary (or any of its 4 JS fallbacks: mediaplex, opusscript, @evan/opus, node-opus) is present. This is why Spotify appeared broken too — Spotify search itself works fine; it fails at the exact same downstream encoding step as everything else.

Fix

"allowScripts": {
    "@discordjs/opus@0.10.0": true
}

Added via npm install-scripts approve @discordjs/opus (npm 12+ native command).

Verification

Rebuilt the deps-production Docker stage in an isolated clone with this change:

npm warn install-scripts 6 packages had install scripts blocked ...
  (no longer lists @discordjs/opus)

$ docker run --rm opus-fix-test find node_modules/@discordjs/opus -name '*.node'
node_modules/@discordjs/opus/prebuild/node-v137-napi-v3-linux-x64-musl-1.2.6/opus.node
node_modules/@discordjs/opus/build-tmp-napi-v3/Release/opus.node

Binary now lands at exactly the path the runtime error was looking for.

Follow-up (not done here — scope kept surgical to the outage)

6 other packages are in the same unapproved state in the production build (@prisma/engines, esbuild, ffmpeg-static, msgpackr-extract, prisma, youtube-dl-exec). None currently show evidence of breaking prod — Prisma engines are separately copied in from the build stage (#1734), ffmpeg/yt-dlp use system binaries not the npm-bundled ones, msgpackr-extract just falls back to a slower pure-JS path. Worth a deliberate review pass to decide per-package whether to approve or leave blocked, tracked separately.


Summary by cubic

Approve @discordjs/opus install script in package.json so native Opus builds under npm@12, restoring music playback in production. Fixes P0 playback outage across all sources.

  • Bug Fixes
    • Cause: npm@12 allowlist blocked @discordjs/opus during npm ci --omit=dev, so no opus.node.
    • Change: Added "allowScripts": { "@discordjs/opus@0.10.0": true } in package.json.
    • Result: Opus builds and loads; playback works again. Verified by rebuild.

Written for commit 7c930e4. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Enabled required installation scripts for the audio processing package to support successful setup.

npm 12's install-scripts allowlist (introduced by the npm bump in the
Docker toolchain fix, #1310) was never approving @discordjs/opus's
native compile step, so node-pre-gyp's fallback-to-build silently
no-op'd during npm ci --omit=dev — no opus.node binary ever landed in
the production image. Every attempt at audio-resource creation
(createAudioResource -> OpusEncoder -> OpusStream -> loadModule) has
been failing in prod as a result, blocking all music playback
regardless of source (YouTube, Spotify-matched, SoundCloud).

Verified fix by rebuilding the deps-production Docker stage in
isolation: opus.node now compiles and lands at the exact path the
runtime error was looking for.
@LucasSantana-Dev LucasSantana-Dev added the ready-for-agent Fully specified, ready for an AFK agent label Jul 10, 2026
@LucasSantana-Dev
LucasSantana-Dev enabled auto-merge (squash) July 10, 2026 03:30
@github-actions github-actions Bot added dependencies Pull requests that update a dependency file size/xs labels Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The package configuration now explicitly allows install-time scripts for @discordjs/opus@0.10.0 through the top-level overrides block.

Changes

Opus installation

Layer / File(s) Summary
Opus script allowlist
package.json
Adds @discordjs/opus@0.10.0 to the allowScripts configuration.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Possibly related issues

  • LucasSantana-Dev/Lucky#1756 — Concerns the missing production binary for @discordjs/opus, which this install-script allowlist may address.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: approving the @discordjs/opus install script to fix the music playback outage.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/discordjs-opus-install-script-blocked

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 1 file

Auto-approved: Enables the install script for @discordjs/opus to restore native opus building, fixing a P0 playback outage.

Re-trigger cubic

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit 9d894e4 into main Jul 10, 2026
41 of 42 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/discordjs-opus-install-script-blocked branch July 10, 2026 04:18
LucasSantana-Dev added a commit that referenced this pull request Jul 10, 2026
…ploy pipeline blocker (#1758)

## Problem

Discovered while trying to deploy #1757 (the opus playback fix): every
deploy currently fails at the migration step.

\`scripts/deploy.sh\` runs \`prisma migrate deploy\` via the **backend**
image (\`docker_compose run --rm --no-deps backend ...\`), which fails:
\`\`\`
Error: Can't write to /app/node_modules/@prisma/engines please make sure
you install "prisma" with the right permissions.
[deploy] ERROR: MIGRATION_FAILED (prisma migrate deploy)
\`\`\`

## Root cause

\`deps-production\`'s \`npm ci --omit=dev\` ships \`node_modules\`
**without** the Prisma migrate schema-engine, since
\`prisma\`/\`@prisma/engines\` are devDependencies. The **bot**
Dockerfile stage already has a fix for exactly this (#1734/#1735): it
copies the full \`@prisma\` from the \`build\` stage and chowns it to
the non-root runtime user. The **backend** stage — which is what
actually runs migrations — never got the same fix. It only chowns
\`/app/packages/backend/dist /app/prisma\`, not
\`/app/node_modules/@prisma\`, and never copies the working engines in
from \`build\` at all.

## Fix

Mirrors the bot stage's existing pattern onto backend:
\`\`\`dockerfile
COPY --from=build /app/node_modules/@prisma ./node_modules/@prisma
...
chown -R backend:nodejs /app/packages/backend/dist /app/prisma
/app/node_modules/@prisma
\`\`\`

## Verification

Built \`production-backend\` in isolation:
\`\`\`
$ docker run --rm backend-fix-test sh -c 'ls -ld
/app/node_modules/@prisma'
drwxr-xr-x 1 backend nodejs ... /app/node_modules/@prisma

$ docker run --rm backend-fix-test sh -c 'find /app/node_modules/@prisma
-iname "*schema-engine*"'
-rwxr-xr-x 1 backend nodejs 22280136 ...
/app/node_modules/@prisma/engines/schema-engine-linux-musl-openssl-3.0.x

$ docker run --rm backend-fix-test sh -lc 'npx prisma migrate status
...'
Error: Connection url is empty. # <- only fails on missing DATABASE_URL
(expected, no real env in this isolated test) — permission error is gone
\`\`\`

## Impact

This is currently blocking **all** deploys to the homelab, including the
P0 opus-playback fix (#1757, already merged). Needs to merge and deploy
ASAP.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the production backend Docker image to include and chown Prisma
engines so `prisma migrate deploy` runs without permission errors.
Unblocks the deploy pipeline.

- **Bug Fixes**
- Copy `@prisma` from the build stage into `/app/node_modules/@prisma`
in the backend image and `chown -R backend:nodejs`.
- Prevents the write error caused by `npm ci --omit=dev` omitting
`@prisma/engines` and running migrations as the non-root `backend` user.

<sup>Written for commit ec5a733.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/LucasSantana-Dev/Lucky/pull/1758?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved production container setup to ensure Prisma database
operations run correctly at runtime.
- Updated file permissions so backend processes can access required
database engine and schema files without elevated privileges.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
LucasSantana-Dev added a commit that referenced this pull request Jul 10, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>2.34.0</summary>

##
[2.34.0](v2.33.1...v2.34.0)
(2026-07-10)


### Features

* **twitch:** use Promise.allSettled for per-event subscription error
logging ([#1749](#1749))
([6691305](6691305))


### Bug Fixes

* [#1699](#1699)
([eef5aee](eef5aee))
* **backend:** migrate webhooks to use canonical timingsafekey
comparison
([#1747](#1747))
([eef5aee](eef5aee))
* **backend:** wrap lastfm routes with asynchandler
([#1726](#1726))
([ce51d86](ce51d86))
* **batch-move:** graceful attachment-fetch degradation + mid-loop
client re-check
([#1750](#1750))
([f21a0ce](f21a0ce))
* **bot:** approve @discordjs/opus install script — P0 music playback
outage ([#1757](#1757))
([9d894e4](9d894e4))
* **ci:** add missing packages field to pnpm-workspace.yaml
([#1760](#1760))
([a4c585d](a4c585d))
* **ci:** remove pnpm shim from bundle-size workflow
([#1759](#1759))
([eaf676f](eaf676f))
* **deploy:** increase validation timeout to 10min
([#1743](#1743))
([07891ec](07891ec))
* **docker:** copy+chown [@prisma](https://github.com/prisma) engines in
production-backend — P0 deploy pipeline blocker
([#1758](#1758))
([a70d0e8](a70d0e8))
* eliminate mock state pollution in bot tests and remove resetMocks
config ([#1741](#1741))
([2e5fd94](2e5fd94))
* **frontend:** prevent state updates after unmount
([#1748](#1748))
([f4e7c45](f4e7c45))
* pin file-type to resolve CI flake
[#1740](#1740)
([#1753](#1753))
([6b8e527](6b8e527))
* reduce Jest maxWorkers and add DB pool config for test stability
([#1751](#1751))
([cfead33](cfead33))
* use fake timers in ReminderService.spec to prevent race condition
([#1745](#1745))
([ba2908c](ba2908c))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file ready-for-agent Fully specified, ready for an AFK agent size/xs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant