Skip to content

[Bug]: On NixOS, the preview browser's library check reports libraries that nix-ld provides, and t3 browser setup can't install them #16871

Description

@nkoynov

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. On NixOS with programs.nix-ld.enable = true and its default library set, let T3 install its preview browser (call html_preview from any thread).
  2. html_preview fails with "This host is missing libraries T3's browser needs (libglib-2.0.so.0, libgobject-2.0.so.0, libnspr4.so, … 22 in all). Run sudo t3 browser setup on the host to install them, then try again."
  3. sudo t3 browser setup finds no apt-get and prints "Install them with your package manager, then run this again."
  4. Give nix-ld the libraries (list under Workaround) and switch. html_preview and html_render now work.
  5. Run t3 browser setup again. It still lists all 22 libraries as missing.

Expected behavior

The library check agrees with what the loader finds when the browser starts, so once the libraries are there, neither T3 nor t3 browser setup reports them missing.

Actual behavior

PreviewBrowserHost.missingLibraries runs ldd <chrome-headless-shell>. On NixOS, ldd runs the glibc loader from the Nix store, and that loader doesn't read nix-ld's library path. The browser itself starts through /lib64/ld-linux-x86-64.so.2, which is nix-ld and does read it. So ldd reports all 22 libraries as not found whether or not nix-ld provides them:

$ NIX_LD_LIBRARY_PATH=<set with the libraries> chrome-headless-shell --version
Google Chrome for Testing 154.0.8037.92
$ NIX_LD_LIBRARY_PATH=<same set> ldd chrome-headless-shell | grep -c 'not found'
22

What follows from that:

  • t3 browser setup never reports a NixOS host as ready.
  • When the browser fails for some other reason on such a host, diagnoseLaunchFailure still blames missing libraries and points at sudo t3 browser setup, which hides the real cause.
  • t3 browser setup can only install libraries with apt-get (DEBIAN_PACKAGES).

A check that trusts the loader would avoid this. For example, report missing libraries only when Chrome's own stderr has the loader's error while loading shared libraries: line (glibc prints it on every distro, nix-ld included). In t3 browser setup, start the browser with --version before listing libraries.

Related: on NixOS this missing-libraries exit is also what triggered the server crash in #16794 for us (the fix is #16555).

Impact

Minor bug or occasional failure

Version or commit

nightly 0.0.46-nightly.20261007.2761 (PreviewBrowserHost.ts is unchanged on main @ 611132c)

Environment

NixOS 26.11 x86_64, nix-ld 2.0.6, T3 executable (Node 26.8.2), Chrome for Testing headless shell 154.0.8037.92

Workaround

Give nix-ld the libraries the headless shell links (nixpkgs attribute names):

programs.nix-ld.libraries = with pkgs; [
  alsa-lib at-spi2-core dbus expat glib libgbm libx11 libxcb libxcomposite libxdamage
  libxext libxfixes libxkbcommon libxrandr nspr nss systemd
];

at-spi2-core provides libatk, libatk-bridge and libatspi, and systemd provides libudev. After a switch, the browser picks them up the next time it starts. t3 browser setup keeps listing them, as described above.

Found and written with Claude Opus 5.5 in T3 Code (OpenCode 2 + cursor-opencode-provider).

Activity

  1. juliusmarminge commented on Oct 7, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks @nkoynov, the code matches your report. Checked against main @ 611132c.

    Root cause. All of the library detection comes from ldd output:

    • missingLibraries runs ldd <executable> with stderr ignored, and counts every <lib> => not found line (apps/server/src/preview/PreviewBrowserHost.ts:92, :118-129). It never launches the browser.
    • t3 browser setup reports ready only when that list is empty (apps/server/src/cli/browser.ts:121-131). It doesn't check whether the browser actually starts. With your 22 false positives it never reaches "ready". As root with apt it would also run apt-get install for nothing (:173-185).
    • diagnoseLaunchFailure checks the sandbox signature first. On Linux it then blames whatever ldd lists, so any unrelated launch failure gets reported as PreviewBrowserLibrariesError (PreviewBrowserHost.ts:99-115).
    • The only automated install path is apt-get with DEBIAN_PACKAGES (PreviewBrowserHost.ts:52, browser.ts:173-185). Without /usr/bin/apt-get (browser.ts:124), setup prints "Install them with your package manager, then run this again" and exits (:166-170). On NixOS that loops forever, because ldd keeps reporting the same libraries.

    I couldn't reproduce the NixOS ldd vs nix-ld loader difference here. The --version vs ldd comparison in your report is the evidence for it.

    Fix. Trust the real loader over ldd:

    1. In setup, run <executable> --version first. If it exits 0, the libraries are fine: skip the library step and report ready.
    2. In diagnoseLaunchFailure, return PreviewBrowserLibrariesError only when the launch output contains glibc's error while loading shared libraries: line. Take the library names from that line, or fall back to ldd only after that signature shows up.
    3. Optionally, on hosts without apt, list the missing libraries without suggesting the rerun loop.

    Related: #16794 / #16555 (same setup flow), and open #16872 (reporting how the html preview browser exited) would pair well with step 2.

    Workaround (from the reporter). Add the headless shell's libraries to programs.nix-ld.libraries (the nixpkgs list in the issue body) and switch. html_preview and html_render then work, even though t3 browser setup still won't say ready until this is fixed.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 7, 2026
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

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions