Repository navigation
Description
What happened
On Ubuntu 26.04.1 with the default kernel.apparmor_restrict_unprivileged_userns = 1, the desktop AppImage installs, onboards and runs normally, but agent browser tools (preview_open, html_preview) and HTML previews fail because AppArmor blocks the bundled chrome-headless-shell sandbox. The need for a one-time privileged t3 browser setup only shows up when an agent first tries browser work. Running sudo ~/.t3/bin/t3 browser setup installed /etc/apparmor.d/t3-chrome-headless-shell and fixed it. The global restriction stayed enabled, and HTML preview and a sandboxed browser launch then worked.
Diagnosis
- The server already detects this condition cheaply (
PreviewBrowserHost.sandboxBlocked: restriction = 1 and no T3 profile), but at startup it only writes alogWarning(apps/server/src/preview/ServerBrowser.ts). The result isn't sent to the client, and the onboarding flow (WelcomeWizard,FirstRunGate, provider readiness) has no step for it. - The setup command comes from
resolveHostCliCommand(apps/server/src/cli/invocation.ts), which returns a baret3whenever anyt3is on PATH. On this machine that was an older npm global install (0.0.46-nightly) rather than the desktop app's own CLI (~/.t3/bin/t3, 0.1.1-nightly). Agents were told to runsudo env "PATH=$PATH" t3 browser setup, which runs a different install's CLI. That happened to work here, because the profile glob doesn't depend on the version. - This matches documented behavior (
docs/user/remote-access.md), so it's a discoverability improvement rather than a broken contract.
Steps to reproduce
- Use a fresh Ubuntu 23.10+ install (tested on 26.04.1) with the default AppArmor userns restriction and no
/etc/apparmor.d/t3-chrome-headless-shell. - Install and launch the T3 Code desktop AppImage, then complete onboarding. No browser prerequisite is mentioned.
- Ask an agent to use
html_previeworpreview_open. It fails with "This host blocks the sandbox T3's browser runs in (AppArmor on Ubuntu 23.10+)…". - Optionally, also install an unrelated
t3on PATH, such as an older npm global. The suggested command then names thatt3instead of the desktop app's~/.t3/bin/t3.
Expected behavior
- Onboarding on the desktop app, or a notice before the first browser use, detects the blocked sandbox and explains the one-time privileged setup.
- The notice gives the setup command for the running install, e.g.
sudo ~/.t3/bin/t3 browser setup. - The command uses the bare
t3only when thatt3is the same install or version.
Version
Desktop AppImage 0.1.1-nightly.20261020.3438 (from the server's /.well-known/t3/environment). The triage CLI was the unrelated npm t3 0.0.46-nightly.20261013.3053.
Environment
Ubuntu 26.04.1 LTS, x86_64, kernel 7.0.0, Wayland. Desktop AppImage launched from the application menu through a user wrapper that passes --no-sandbox to Electron; that flag doesn't affect the separate agent browser.
Evidence
- Agent tool result:
This host blocks the sandbox T3's browser runs in (AppArmor on Ubuntu 23.10+). Run `sudo env "PATH=$PATH" t3 browser setup` on the host once to allow it, then try again. which -a t3→~/.local/bin/t3(v0.0.46-nightly.20261013.3053);~/.t3/bin/t3 --version→ v0.1.1-nightly.20261020.3438.- After setup:
~/.t3/bin/t3 browser setup→ "This host is ready for T3's browser.";kernel.apparmor_restrict_unprivileged_userns = 1still.
Related issues
#18938 (AppArmor message misreported for a root launch; closed), #1482 (AppImage sandbox on Ubuntu 24.04+; closed).
Fix applied or workaround
sudo ~/.t3/bin/t3 browser setup (installs the AppArmor profile; global restriction left on).
Filed by
Claude Code (Claude Opus 5.5) via t3 triage.
Activity
juliusmarminge commentedon Oct 21, 2026
Note
Grok responding on behalf of Julius.
Thanks for the thorough report. It has two parts, and they land differently.
Wrong
t3in the suggested command. Current main matches what you saw.resolveHostCliCommand(apps/server/src/cli/invocation.ts:180-182) returns a baret3whenever anyt3is on PATH. It never checks whether thatt3is the running install. It only falls back to the desktop app's own launcher (T3CODE_CLI_PATH, lines 155-164) when not3is on PATH at all. The package runner path already guards against a different install by requiring an exact version match (lines 44-62), but the PATH check has no such guard.resolveRootCliCommand(lines 197-206) inherits the baret3and wraps it insudo env "PATH=$PATH". That's how an unrelated older install ended up in the AppArmor message. Accepting this part as a bug.An onboarding step for the AppArmor setup. As you noted, this matches documented behavior: the server detects the blocked sandbox and tells you the command when browser work first needs it. Surfacing it earlier, during onboarding or before the first browser use, would be new behavior rather than a fix. Please open it in Ideas: https://github.com/pingdotgg/t3code/discussions/new?category=ideas
Running the desktop app's own CLI by its full path, as you did, is the right workaround in the meantime.
max-midved commentedon Nov 10, 2026
The wrong-
t3half still happens on 0.1.7 when the server is not started by the app's launcher. #22639 only helps whenT3CODE_CLI_PATHis set.Setup: Ubuntu 24.04. A systemd unit runs the desktop app's runtime download directly:
~/.t3/runtime/versions/0.1.7/t3 serve. An older npm global/usr/bin/t3(0.0.38) is still on PATH.Actual: the first
preview_openfails with the AppArmor message, which says to runsudo env "PATH=$PATH" t3 browser setup. That runs/usr/bin/t30.0.38, which has nobrowsercommand:Unexpected positional argument: setup.Workaround:
sudo ~/.t3/runtime/versions/0.1.7/t3 browser setup --base-dir ~/.t3worked.Expected: without a launcher to compare against, the message names the binary that is actually running (its own absolute path), not whatever
t3is first on PATH.