Skip to content

Streaming JSON in custom/* modules no longer renders any text. #4522

Description

@uhs-robert

Issue

Streaming JSON in custom/* modules no longer renders text. Plain-text streaming is unaffected.

Any custom/* that runs a long-lived command emitting continuous JSON frames to stdout (with "return-type": "json" and "interval": 0) appears as an empty label on the bar. Polling / one-shot commands still render.

This also breaks common patterns like swaync-client -swb (see: SwayNotificationCenter Waybar example).

Notes

  • Built-in modules render normally.
  • Non-streaming custom/* (exec returns once per interval) render normally.
  • Affected examples in my setup:
    • custom/cava (audio visualizer stream)
    • custom/notifications (e.g., swaync-client -swb)
  • GTK widget tree shows the module label nodes (e.g., label#custom-cava.module), but the visible text is blank.
  • Waybar logs show no JSON parse errors when the JSON is valid, and no other runtime errors.
  • Replacing the stream with a polled one-shot (e.g., piping to head -n1 or adding a --once flag) restores visible output immediately.
  • Plain-text streaming works (when return-type is omitted and raw text is formatted).
  • JSON streaming fails only when return-type: "json" and interval: 0 (long-lived process).

Suspected regression window

Last known good: source build from late Sep 2025.
Broken after rebuilding from source on Oct 1–2, 2025.

Minimal Steps to Reproduce

  1. Create a streaming generator (or use this swaync example):

    # ~/.config/waybar/scripts/fake_cava.py
    #!/usr/bin/env python3
    import time, itertools
    bars = ["▁","▂","▃","▄","▅","▆","▇","█"]
    for i in itertools.cycle(range(len(bars))):
        s = " ".join(bars[(i + j) % len(bars)] for j in range(10))
        print('{"text":"%s"}' % s, flush=True)
        time.sleep(0.5)
  2. Use this Waybar config (streaming, interval: 0):

    {
      "layer": "top",
      "position": "top",
      "modules-left": ["custom/cava"],
      "custom/cava": {
        "exec": "python3 -u ~/.config/waybar/scripts/fake_cava.py",
        "return-type": "json",
        "interval": 0,
        "restart-interval": 0,
        "format": "{text}",
        "escape": true,
        "tooltip": false
      }
    }
  3. Launch Waybar and observe: the custom/cava label exists in the widget tree, but no text is rendered.

Expected Result

Streaming custom/* modules that continuously emit valid JSON frames should render their text, as in previous versions.

Video

recording-2025-10-02_14h41m57s.mp4

Debug Logs

waybar-trace.log

System Environment

Waybar: Waybar v0.14.0
Kernel: 6.16.8-200.fc42.x86_64
OS: "Fedora Linux 42 (KDE Plasma Desktop Edition)"
GTK: 3.24.49
gtkmm: 3.24.10
Wayland: 1.24.0
Hyprland: Hyprland 0.51.1 built from branch  at commit 71a1216abcc7031776630a6d88f105605c4dc1c9  ([gha] Nix: update inputs).
Date: Mon Sep 22 20:54:03 2025
Tag: v0.51.1, commits: 6436
built against:
 aquamarine 0.9.4
 hyprlang 0.6.4
 hyprutils 0.8.4
 hyprcursor 0.1.13
 hyprgraphics 0.1.6

no flags were set

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions