Skip to content

v0.12.0 exits 0 and writes no output file on ubuntu-24.04 runners; v0.11.0 records the same tape #787

Description

@vahapogut

On an ubuntu-24.04 GitHub Actions runner, vhs v0.12.0 runs a tape to completion, prints Creating <file>.gif..., prints the publish hint, exits 0, and writes no file. v0.11.0 records the same tape on the same runner without complaint.

The gap between the two printed lines is about 200 to 440 milliseconds, which is far too short to encode twenty seconds of terminal, so it looks like the encode never starts rather than failing.

Controlled comparison

Two runs of the same job, on the same runner image, from two commits whose only functional difference is the version passed to charmbracelet/vhs-action@v2.1.1:

Run vhs Result
34459564668 v0.12.0 exits 0, no file anywhere on the filesystem
34460025896 v0.11.0 writes a 201 KB, 1200x700, 224 frame GIF

The diff between the two commits is one line plus comments:

-          version: v0.12.0
+          version: v0.11.0

Both runs are public, so the full logs are readable.

Environment

vhs     v0.12.0 (db96d73)   /opt/hostedtoolcache/vhs/0.12.0/x64/...
ttyd    1.7.7-40e79c7
ffmpeg  6.1.1-3ubuntu5
chrome  Google Chrome 152.0.7977.64  (chromium 152.0.7977.0 also present)
os      Ubuntu 24.04.5 LTS, x86_64
image   ubuntu-24.04, version 20260831.293.1
action  charmbracelet/vhs-action v2.1.1

Tape

Output docs/demo.gif

Require trustdiff

Set Shell bash
Set FontSize 16
Set Width 1200
Set Height 700
Set Padding 20
Set TypingSpeed 40ms

Type "trustdiff check npm:express@4.19.2 pypi:requests cargo:serde"
Sleep 500ms
Enter
Wait+Screen@300s /Exit code/
Sleep 6s

trustdiff is a CLI on PATH; any command that prints a screen of text and ends with a line matching the Wait+Screen pattern should do.

Observed

Every tape step executes and every Wait+Screen matches, so the terminal side is working. Then:

09:16:20.0019515Z  Creating docs/demo.gif...
09:16:20.0021686Z
09:16:20.4461187Z  Host your GIF on vhs.charm.sh: vhs publish <file>.gif

vhs docs/demo.tape run by hand in the same job exits 0. Afterwards docs/ contains no gif, and find / -name 'demo.gif' -type f -newermt '-5 minutes' finds nothing.

Ruled out

Four things, each tested on its own before the version was suspected:

  • Set Columns / Set Rows. The tape originally used them, and they are new in v0.12.0, so they were the obvious suspect. Replacing them with Set Width / Set Height changed nothing.
  • Missing ffmpeg. The ubuntu-24.04 image does not carry ffmpeg. Installing it changed nothing here, but see the note below.
  • A Hide / Show block. The tape warmed a cache off camera inside one. Removing it entirely changed nothing.
  • Tape length. Cut from two recorded commands to one. Changed nothing.

Possibly a separate issue

vhs does not appear to check for ffmpeg before starting, and a run without it fails in exactly the shape above: tape completes, Creating ....gif... prints, exit 0, no file. That made this bug considerably harder to isolate, because the first thing anyone checks produces the same symptom. A startup check, or an error when the encode produces nothing, would turn both cases into something a reader can act on. Happy to open that separately if you would rather keep them apart.

Thanks for vhs. The recording it produces is exactly what the project wanted.

Activity

  1. tranzystorekk commented on Sep 10, 2026

    @tranzystorekk
    Contributor

    Same symptoms when attempting to package vhs 0.12.0 for Void Linux.

    I'm speculating that the issue lies somewhere in the ffmpeg invocation, but the fact that vhs seemingly doesn't check for or report any errors, or even have a verbose option to get more info from the tools it runs, doesn't help.

  2. gtartari-eurofunk commented on Sep 10, 2026

    @gtartari-eurofunk

    Here https://github.com/charmbracelet/vhs/blob/main/evaluator.go#L186 the context used for rendering (the line below) is cancelled.
    One potential fix could be to use different contexts for rendering and recording.

  3. added a commit that references this issue on Sep 13, 2026
  4. astrostl commented on Sep 13, 2026

    @astrostl

    Same, reverted to 0.11 for now. Still LOVE the tool!

  5. programmersd21 commented on Sep 14, 2026

    @programmersd21

    same here i got the same issue but locally in my cachyos+hyprland (ml4w) setup i checked ttyd ffmpeg vhs all version all deps everything but a gif is never produced

    edit: use

    cd /tmp
    curl -fL -o vhs.tar.gz https://github.com/charmbracelet/vhs/releases/download/v0.11.0/vhs_0.11.0_Linux_x86_64.tar.gz
    tar -xzf vhs.tar.gz
    sudo install -Dm755 vhs_0.11.0_Linux_x86_64/vhs /usr/local/bin/vhs
    vhs --version

    and the gif also rendered for my case too using 0.11.0

  6. hartsock commented on Sep 14, 2026

    @hartsock

    Same failure on macOS, and both open fixes work there.

    Environment: macOS 26.6.2 arm64, vhs 0.12.0 (Homebrew bottle), Chrome 153.0.8010.36, ffmpeg 9.0.1, ttyd 1.7.7, Go 1.27.1.

    Results with a six-line tape:

    Build Exit Output
    Homebrew 0.12.0 0 no file
    #788 at 7e0c332 0 400x200 GIF, 33 frames
    #789 at 2f00c0e 0 400x200 GIF, 33 frames

    With VHS_TEST_BROWSER=1, the new tests pass on both branches. As a control, I restored evaluator.go and vhs.go from v0.12.0 on the #789 branch and reran TestRenderWritesOutput. It failed with no output written, so the test catches this bug.

    Before finding these PRs I patched it locally with v.Render(context.WithoutCancel(ctx)). That also produces a file, but it ignores cancellation of the parent context during encoding. The separate recorder context in #788 and #789 avoids that.

  7. 11 remaining items

  8. nedzen commented on Sep 20, 2026

    @nedzen

    Independent repro, macOS 26.6.2 arm64 (Homebrew vhs 0.12.0, ttyd 1.7.7, ffmpeg 9.0.1).

    One extra data point not covered above: downgrading ffmpeg does NOT fix it. With ffmpeg@7.1.5 first on PATH (same tape, minimal 6-line repro: Output test.gif + single Type + Enter + Sleep), behavior is identical — Creating test.gif... + publish hint + exit 0 + no file anywhere on disk (searched /tmp, cwd, tape dir, and ~/Library).

    Test matrix on this machine:

    Build Result
    vhs 0.12.0 (bottle) exit 0, no file
    vhs 0.12.0 + ffmpeg@7.1.5 on PATH exit 0, no file (same)
    ttyd standalone healthy — serves sessions, HTTP 200, stays alive
    frame capture (per @gauravbluepi) n/a tested here, but recording side completes

    Also reproduced from a real PTY in an interactive terminal pane (not CI/sandbox), and with tapes containing real API calls — so no sandbox/PTY excuse. Matches @gtartari-eurofunk's context-cancellation diagnosis: the encode step is cancelled before it starts regardless of ffmpeg version. Confirming the fix PRs (#788/#789) are the way forward; will report back if a mainline build changes anything on this machine.

  9. andrinoff commented on Sep 24, 2026

    @andrinoff
    Member

    This is so crazy. Sorry for the long review. Please, cc me next time something like this comes up.

    For anyone curious, this bug was caused by linting, which is why i didn't think to check.

    Sorry for the inconvenience, everybody, will release now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions