Skip to content

[bugfix]: dreamverse modal bypasses ENTRYPOINT — set ffmpeg env + key check - #1413

Merged
SolitaryThinker merged 2 commits into
hao-ai-lab:mainfrom
FoundationResearch:bugfix/dreamverse-modal-bypass-fix
May 29, 2026
Merged

[bugfix]: dreamverse modal bypasses ENTRYPOINT — set ffmpeg env + key check#1413
SolitaryThinker merged 2 commits into
hao-ai-lab:mainfrom
FoundationResearch:bugfix/dreamverse-modal-bypass-fix

Conversation

@alexzms

@alexzms alexzms commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Modal's @modal.web_server decorator invokes serve() directly (Popen the dreamverse-server) and bypasses the image's ENTRYPOINT (apps/dreamverse/docker/docker_entrypoint.sh). The bypassed entrypoint normally does two things that silently no-op on Modal:

  1. :?-validates CEREBRAS_API_KEY and GROQ_API_KEY (fails the container fast if either is missing from the mounted secret).
  2. Sources ffmpeg-env.sh, which exports FASTVIDEO_FFMPEG_BIN=/opt/ffmpeg-native/bin/ffmpeg.

Symptoms observed

Deploying the post-#1394 UI image (dreamverse-ui-cuda12.9.1-sha-2c13793) on Modal:

  • No ffmpeg, video silently broken. /opt/ffmpeg-native/bin is not on the container PATH (apps/dreamverse/docker/Dockerfile:24). With FASTVIDEO_FFMPEG_BIN unset, av_streaming.py:28's shutil.which("ffmpeg") returns None and av_fmp4 muxing has no encoder.
  • Missing keys surface at first request, not boot. A dreamverse-api-keys secret with placeholder values lets the container come up fine; prompt rewriting then fails on the first user request instead of at boot.

Fix

Both changes in apps/dreamverse/scripts/modal/modal_app.py:

  1. Set FASTVIDEO_FFMPEG_BIN=/opt/ffmpeg-native/bin/ffmpeg and FASTVIDEO_VIDEO_CODEC=libx264 in image.env so av_streaming finds the native ffmpeg the Dockerfile builds.
  2. Add a fail-fast guard in serve() that checks the required secret entries before launching the server, mirroring the entrypoint's :? behavior.

A comment block above the env dict documents why these are needed (entrypoint bypass), so the next reader doesn't lose the context.

Test evidence

  • pre-commit run --files apps/dreamverse/scripts/modal/modal_app.py and python -c "import ast; ast.parse(open(...))" pass.
  • The ffmpeg gap was empirically discovered while bringing up the dreamverse Modal deploy with the post-[bugfix] Fix Dreamverse Modal compile warmup latency #1394 image; setting FASTVIDEO_FFMPEG_BIN in image.env was the workaround that made av_streaming's shutil.which resolve to the right binary during that session.
  • The key fail-fast is mechanical (re-raises RuntimeError when os.environ.get(k) is empty for either required key); the message names the missing key(s) and points at the README so the operator knows exactly what to fix.

… check

Modal's @modal.web_server decorator invokes serve() directly (Popen
dreamverse-server) and bypasses the image's ENTRYPOINT
(apps/dreamverse/docker/docker_entrypoint.sh). The bypassed entrypoint
normally does two things, both of which silently no-op on Modal:

1. ``:?``-validates CEREBRAS_API_KEY and GROQ_API_KEY (fails the container
   fast if either is missing from the mounted secret).
2. Sources ffmpeg-env.sh, exporting
   FASTVIDEO_FFMPEG_BIN=/opt/ffmpeg-native/bin/ffmpeg.

Symptoms observed when deploying the post-hao-ai-lab#1394 UI image
(dreamverse-ui-cuda12.9.1-sha-2c13793):

- /opt/ffmpeg-native/bin is not on the container PATH (set in
  apps/dreamverse/docker/Dockerfile line 24).  With FASTVIDEO_FFMPEG_BIN
  unset, av_streaming.py:28's shutil.which("ffmpeg") returns None and
  av_fmp4 muxing silently has no encoder.
- A misconfigured dreamverse-api-keys secret (e.g. placeholder values)
  lets the container boot fine; prompt rewriting then fails on the first
  user request instead of at boot.

Fix, both in apps/dreamverse/scripts/modal/modal_app.py:

- Set FASTVIDEO_FFMPEG_BIN and FASTVIDEO_VIDEO_CODEC in image.env so
  av_streaming finds the native ffmpeg the Dockerfile builds.
- Add a fail-fast guard in serve() that checks the required secret
  entries before launching the server, mirroring the entrypoint's ``:?``
  behavior.
@mergify mergify Bot added the type: bugfix Bug fix label May 29, 2026
@mergify

mergify Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 PR merge requirements

Waiting for

  • #approved-reviews-by>=1
  • check-success=full-suite-passed
This rule is failing.
  • #approved-reviews-by>=1
  • check-success=full-suite-passed
  • check-success=fastcheck-passed
  • check-success~=pre-commit
  • title~=(?i)^\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model|skill|skills|infra)\]

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the Modal application script to replicate environment validation and setup that is normally handled by the Docker entrypoint but bypassed by @modal.web_server. Specifically, it defines required secret keys, configures environment variables for the native ffmpeg binary and video codec, and adds a runtime check to ensure all required API keys are present before starting the server. The review feedback suggests improving the API key validation by stripping whitespace from the environment variables to ensure whitespace-only keys are correctly identified as missing.

)
@modal.web_server(8009, startup_timeout=4800)
def serve():
missing = [k for k in _REQUIRED_SECRET_KEYS if not os.environ.get(k)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Checking not os.environ.get(k) will evaluate to False if the environment variable is set to a whitespace-only string (e.g., " "). Stripping the value and defaulting to an empty string ensures that empty or whitespace-only API keys are correctly caught as missing.

Suggested change
missing = [k for k in _REQUIRED_SECRET_KEYS if not os.environ.get(k)]
missing = [k for k in _REQUIRED_SECRET_KEYS if not os.environ.get(k, "").strip()]

… check

Addresses gemini-code-assist's medium-priority comment on hao-ai-lab#1413: the prior
``not os.environ.get(k)`` only catches missing or empty entries, so a
``dreamverse-api-keys`` secret with a whitespace-only value (e.g. a stray
``"   "`` left in place of a real key) would pass the guard and the
``RuntimeError`` would not surface.  Strip the value (after collapsing
``None`` to ``""``) before truthiness-checking so unset, empty, and
whitespace-only all read as missing.
@alexzms

alexzms commented May 29, 2026

Copy link
Copy Markdown
Collaborator Author

Pushed e1bde40a to address gemini's whitespace nit: not (os.environ.get(k) or "").strip() now collapses unset (None), empty (""), and whitespace-only (" ") values into the "missing" set.

@SolitaryThinker
SolitaryThinker merged commit d6119c1 into hao-ai-lab:main May 29, 2026
8 of 9 checks passed
@SolitaryThinker
SolitaryThinker deleted the bugfix/dreamverse-modal-bypass-fix branch May 29, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants