Skip to content

Let an operator actually reach the browser limits - #96

Merged
davidmckayv merged 1 commit into
mainfrom
fix/expose-browser-limits
Aug 21, 2026
Merged

Let an operator actually reach the browser limits#96
davidmckayv merged 1 commit into
mainfrom
fix/expose-browser-limits

Conversation

@davidmckayv

Copy link
Copy Markdown
Contributor

Two problems with the browser cap #90 added, both found by driving it against the real container
rather than by reading the diff.

The settings were unreachable. COMPUTER_MAX_BROWSERS and COMPUTER_BROWSER_IDLE_MS are read by
profiles.ts and were declared nowhere, so COMPUTER_MAX_BROWSERS=1 docker compose up did nothing:
the container never saw the variable. A limit an operator cannot set is not a limit.

Declaring them exposed the real bug. An unset variable in a compose file arrives as an empty
string rather than as absent, so process.env.X ?? 8 never fires and Number("") is zero. Every
deployment that had not set a cap would have got a cap of zero: every browser closed the moment it
opened, which reads as a broken computer rather than a misconfigured one. Anything that is not a
positive number now falls back, because "I typed this wrong" and "I did not set it" both mean the
default.

This is the second time today an empty-string environment value has been the bug worth catching, the
first being OPENBOT_SINGLE_USER. Worth remembering when adding a setting.

Proof

Against the real container, rebuilt:

  • COMPUTER_MAX_BROWSERS=1: opening beta's browser closed alpha's, logged
    computer-browser-closed with the cap on running browsers was reached, and left the Bot that
    just asked running.
  • alpha came straight back on its next request, because the profile is on the volume. Closing one
    costs a relaunch and nothing else.
  • Variable empty: three Bots all kept their browsers, so the default applied rather than zero.

Two more tests, one of which states the failure as the behaviour it would have caused.
bun run test:ci: 1010 tests, 0 fail.

Where it runs

  • New state that outlives a request? None.
  • What happens on the second replica? Each computer container enforces its own limits, which is
    the right scope: the memory being bounded is that container's.
  • Anything serialised? No.
  • Anything fanned out to a browser? No.
  • New listener, port, or schedule? None beyond the idle sweep Put shared state where every replica can see it, and bound what grows #90 added, which is unrefed.

Found by driving them rather than by reading, and the second half is the reason it was worth driving.

`COMPUTER_MAX_BROWSERS` and `COMPUTER_BROWSER_IDLE_MS` were read by the code and declared nowhere, so
setting either on `docker compose up` did nothing at all: the container never saw them. They are in
the compose environment now and in the configuration reference.

Declaring them exposed the real bug. An unset variable in a compose file arrives as an empty string
rather than as absent, and `Number("")` is zero, so `?? 8` never fired and every deployment that had
not set a cap would have got a cap of zero — every browser closed the moment it opened, a computer
that looks broken rather than misconfigured. Anything that is not a positive number now falls back,
because "I typed this wrong" and "I did not set it" both mean the default.

Driven against the real container. With the cap at one, opening a second Bot's browser closed the
first and logged why, the closed Bot came straight back on its next request because the profile is on
the volume, and with the variable empty three browsers stayed up.
@davidmckayv
davidmckayv merged commit 37b576c into main Aug 21, 2026
6 checks passed
@davidmckayv
davidmckayv deleted the fix/expose-browser-limits branch August 21, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant