usestrix/strix · error · SystemExit

Viewer UI is not built.\nBuild it with: cd strix/interface/v

Error message

Viewer UI is not built.\nBuild it with: cd strix/interface/viewer/frontend && npm ci && npm run build

What it means

SystemExit(1) with 'Viewer UI is not built' raised by the viewer CLI (strix/interface/viewer/cli.py main()) when bundle_is_built() reports the frontend asset bundle is missing. The viewer serves a pre-built JS/CSS bundle from strix/interface/viewer/frontend; when the package was installed from source without building the frontend, serving is impossible, so the CLI exits with the exact build command to run.

Source

Thrown at strix/interface/viewer/cli.py:63

        default=0,
        help="Port to serve on (default: an available ephemeral port).",
    )
    parser.add_argument("--host", default="127.0.0.1", help=argparse.SUPPRESS)
    parser.add_argument(
        "--no-open",
        action="store_true",
        help="Do not open the browser automatically.",
    )
    args = parser.parse_args(argv)

    console = Console()

    if not bundle_is_built():
        console.print(
            "[bold red]Viewer UI is not built.[/]\n"
            "Build it with: [cyan]cd strix/interface/viewer/frontend && npm ci && npm run build[/]"
        )
        raise SystemExit(1)

    run_dir = _resolve_run_dir(args.run, console)

    httpd, url, token = serve(
        run_dir,
        host=args.host,
        port=args.port,
        open_browser=not args.no_open,
    )
    # The tokened URL is what authorizes the browser (steering, report sending,
    # history). Print it rather than the bare URL so the operator -- and only
    # the operator -- can open or share an authorized link.
    open_url = authorized_url(url, token)

    run_name = run_dir.name
    summary = read_run_summary(run_dir)
    live = not summary.get("finished", False)

View on GitHub (pinned to 8551339130)

Solutions

  1. Run the exact command shown: cd strix/interface/viewer/frontend && npm ci && npm run build (requires Node.js/npm installed)
  2. If Node is missing, install it first (e.g. via nvm or system package manager), then re-run the build
  3. Use an official release wheel/PyPI install, which ships the pre-built bundle, instead of a source checkout
  4. In Dockerfiles, make the frontend build step fatal (set -e) so a broken build fails the image build instead of deferring to runtime

Example fix

# before (Dockerfile, silent failure)
RUN cd strix/interface/viewer/frontend && npm ci && npm run build || true
# after
RUN cd strix/interface/viewer/frontend && npm ci && npm run build
Defensive patterns

Strategy: validation

Validate before calling

from strix.interface.viewer.bundle import bundle_is_built  # adjust import to actual module

def assert_viewer_ready():
    if not bundle_is_built():
        raise SystemExit(
            "Viewer UI missing. Run: cd strix/interface/viewer/frontend && npm ci && npm run build"
        )

Try / catch

try:
    main(argv)
except SystemExit as e:
    if e.code == 1 and not bundle_is_built():
        subprocess.run(["npm", "ci"], cwd="strix/interface/viewer/frontend", check=True)
        subprocess.run(["npm", "run", "build"], cwd="strix/interface/viewer/frontend", check=True)
        main(argv)
    else:
        raise

Prevention

When it happens

Trigger: Running the viewer (e.g. `strix viewer` / python -m strix.interface.viewer.cli) from a source checkout or a wheel built without the frontend step. bundle_is_built() finds no dist bundle, prints the message, and raises SystemExit(1) before binding any port.

Common situations: Fresh git clone + `uv run strix ...` without building the frontend; CI installing the package with --no-build-isolation that skips the npm step; node/npm absent from the image so the optional frontend build silently skipped; downstream packagers (Debian, conda) shipping a Python-only build; npm ci failing midway in a Docker build and the error being ignored.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/551d957393e61818. Report an issue: GitHub.