Skip to content

[Bug]: Remote PDF previews start a download instead of rendering after server-browser switch #16853

Description

@jdlar18

Before submitting

  • I searched existing issues and did not find a duplicate of this PDF/server-browser regression.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server (preview), apps/web, apps/desktop

Summary

PDF links from a remote environment no longer display in the integrated browser of the macOS desktop client after the environment-hosted browser change in #15328. The PDF is served successfully, but the server browser starts a download instead of rendering it. T3 preview automation reports page.goto: Download is starting.

The user reports that this workflow previously worked. The current failure was reproduced independently through the T3 preview tools; an old-release A/B test has not been performed.

Steps to reproduce

  1. Run the current nightly T3 server on a separate Linux x64 host and connect to it using the macOS T3 desktop app.
  2. Put a valid PDF in the remote project's workspace and have a thread link it, e.g. [Report](/absolute/workspace/docs/report.pdf).
  3. Open that PDF in the integrated browser from the chat file link. The environment advertises server-browser support, so remote tabs use the server runtime.
  4. For an independent reproduction, open a browser tab through preview_open, then call preview_navigate with the PDF's fresh signed /api/assets/<redacted>/report.pdf URL.
  5. Repeat with the same asset path through a direct LAN HTTP origin and through the host's existing HTTPS reverse-proxy origin.

Expected behavior

The PDF renders inside T3 as it did before the change. If the selected browser cannot render PDFs, T3 should offer a working document viewer or an explicit external-open/download fallback instead of treating the document as a navigable page that fails to load.

Actual behavior

The macOS client does not show the linked PDF. In the server-browser reproduction, both HTTP LAN and HTTPS asset URLs fail navigation with:

Preview automation navigate failed: page.goto: Download is starting

Evaluating the active server browser returns:

{
  "pdfViewerEnabled": false,
  "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/154.0.8037.92 Safari/537.36"
}

Independent GET requests through LAN, loopback, and HTTPS all return 200, Content-Type: application/pdf, Content-Length: 1559562, and bytes starting with %PDF-1.4. The file exists and the signed URL was unexpired during reproduction. This is not specific to the LAN route.

Regression investigation

#15328 merged on 2026-10-06 at 15:04:28 UTC, as ac8e9453ca0948469ccf5651b765086d8d9ecd64.

  • openFileInPreview.ts now passes the runtime selected by previewRuntimeFor when opening file/URL previews.
  • previewRuntime.ts selects server for environments supporting the server browser. Native desktop rendering is restricted to the desktop's own primary environment; remote environments stream the server tab.
  • PreviewBrowser.ts installs Chrome for Testing headless shell, shared by server-browser tabs and HTML rendering.
  • ServerBrowserContexts.ts launches it with headless: true.

This strongly points to the browser-runtime switch exposing the shell's unavailable PDF viewer, rather than an intentional PDF-disable setting. Current main (611132c171, checked 2026-10-07) retains this path; no specific fix was found. The live failure was reproduced on the installed nightly, not by building main.

Impact

Major degradation or frequent failure: generated study/report PDFs cannot be viewed in the remote integrated browser.

Version or commit

Server/web deployment reports 0.0.46-nightly.20261007.2774. Source reviewed: main @ 611132c171f3a821bd2e32f22261135cef6330ac.

Environment

Client: macOS T3 desktop app connected to a separate environment (exact desktop version not collected).
Server: Linux x64, systemd user service, Chrome for Testing headless shell 154.0.8037.92.
Routes tested: direct trusted-LAN HTTP, loopback HTTP, and existing reverse-proxy HTTPS. No credentials or signed asset tokens included.

Related reports

Workaround / possible fix

The asset itself remains retrievable: open its fresh signed URL in an external PDF-capable browser, or download it and use a native PDF reader.

Possible fix directions: render PDFs through a dedicated viewer such as PDF.js, or keep a PDF-capable client rendering path for remote desktop tabs. At minimum, handle download-start navigation explicitly with a usable fallback. Merely switching LAN HTTP to HTTPS does not fix this reproduction.

Generated with GPT-6.1-Sol. Harness: Codex through T3 Code.

Activity

  1. juliusmarminge commented on Oct 7, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the detailed report. The regression checks out against current main.

    Root cause

    How the failure is handled today

    • The download event is saved on the server and offered to the tab's controlling viewer as a "Downloaded …" toast (ServerBrowser.ts#L821, #L857-L885, ServerBrowserSurface.tsx#L126-L137). If no controller is attached when the download finishes, nothing is offered. I haven't confirmed whether that happens on first open from a chat link.
    • The initial goto error on tab creation is swallowed (ServerBrowser.ts#L839-L845). The tab is left with no rendered document and no explanation.
    • Automation navigation only rewrites ERR_* errors. "Download is starting" is rethrown raw (ServerBrowser.ts#L1175-L1197), which matches the preview_navigate failure you saw.

    Minimal fix
    Treat a main-frame navigation that turns into a download as a distinct outcome. Report a clear "this file can't be shown here" state in the tab, with Open externally / Download actions that use the existing download route. Return a typed error from automation navigate instead of the raw Playwright message. Make sure the offer still reaches the viewer when the download finishes before a controller attaches.

    Larger options (design call)

    Related: #15929, #16071, #15328.

  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