Skip to content

fix(config): stop empty boolean env vars from switching flags on - #5838

Open
Lesereingrape wants to merge 7 commits into
browser-use:mainfrom
Lesereingrape:fix/empty-boolean-env-vars
Open

Lesereingrape wants to merge 7 commits into
browser-use:mainfrom
Lesereingrape:fix/empty-boolean-env-vars

Conversation

@Lesereingrape

@Lesereingrape Lesereingrape commented Sep 18, 2026 •

Copy link
Copy Markdown

What

Fixes #5837.

_env_bool() replaces the six copies of os.getenv(NAME, default).lower()[:1] in 'ty1' on CONFIG. The only behaviour that changes is the one that was inverted: a boolean env var that is present but empty now reads False instead of True.

def _env_bool(name: str, default: str = 'false') -> bool:
	"""Read a boolean environment variable, treating an unset or empty value as False.

	`os.getenv(name).lower()[:1] in 'ty1'` answers True for an empty value, because
	substring containment makes '' a match for any string. Membership is therefore
	tested against an explicit tuple of true-ish first characters.
	"""
	return os.getenv(name, default).lower()[:1] in ('t', 'y', '1')

x[:1] in 'ty1' is substring containment, and '' is a substring of everything — so ANONYMIZED_TELEMETRY= in a .env, or a docker-compose.yml list entry written without a value, switched telemetry, cloud sync, version checks and the rest on. '0' and 'no' were already parsed correctly; '' was the only broken input, which is why the fix is the container type rather than the value list.

Why this shape

  • Defaults untouched. Every property keeps its own default argument, so ANONYMIZED_TELEMETRY and BROWSER_USE_VERSION_CHECK still default to True when unset and SKIP_LLM_API_KEY_VERIFICATION still defaults to False. BROWSER_USE_CLOUD_SYNC still inherits str(self.ANONYMIZED_TELEMETRY) — and test_cloud_sync_inherits_telemetry passes.
  • The accepted spellings are unchanged. 'true', 'True', 'TRUE', 'yes', 'y', '1' still read True; 'false', 'no', 'n', '0', ' ', 'maybe' still read False. Measured value-by-value before and after, '' is the only row that differs:
ANONYMIZED_TELEMETRY=         pristine   patched
'true'                            True      True
'True'                            True      True
'TRUE'                            True      True
'yes'                             True      True
'y'                               True      True
'1'                               True      True
'false'                          False     False
'False'                          False     False
'no'                             False     False
'n'                              False     False
'0'                              False     False
''                                True     False   <- the only change
'  '                             False     False
'maybe'                          False     False

Testing

Added test_empty_boolean_env_vars_are_false to TestLazyConfig in tests/ci/infrastructure/test_config.py, alongside the existing env-var tests and in the same save/restore style. It covers five of the six properties; IN_DOCKER is left out because it ORs in is_running_in_docker(), whose answer depends on the machine rather than on the parse.

Fails before the fix, passes after:

$ pytest tests/ci/infrastructure/test_config.py -q -o addopts=""
pristine config.py:  2 failed, 4 passed   <- test_empty_boolean_env_vars_are_false + pre-existing test_path_configuration
patched config.py:   1 failed, 5 passed   <- only test_path_configuration, which fails on main too

Whole tests/ci/infrastructure directory, same branch, source only flipped:

pristine  2 failed, 138 passed, 8 skipped
patched   1 failed, 139 passed, 8 skipped

Exactly one test flips and it is the new one. The remaining failure is TestLazyConfig::test_path_configuration, which fails identically on unmodified main in this checkout.

CI's lint jobs:

  • uv run ruff check --no-fix --select PLE browser_use/config.py tests/ci/infrastructure/test_config.py → All checks passed!
  • ruff check with the repo config on the same two files → All checks passed!
  • codespell on the same two files → no findings
  • ruff format --check → clean. Worth flagging how I checked this, because it initially looked red: run against the working-tree files it reports "would be reformatted", and so does unmodified main — core.autocrlf gives this checkout CRLF files. Against LF-normalised copies of the same two files it reports 2 files already formatted, so the complaint is the checkout, not the diff.
  • I did not run pyright (job lint-typecheck) or pre-commit run --all-files: pre-commit and pyright are not installed in the venv I used, and is_running_in_docker is @cache-decorated and imported from the package, so a partial environment would have produced noise rather than signal. The type surface of this change is str -> bool from os.getenv, unchanged from what it replaced.

Overlap with existing PRs

#5198, #4343 and #4348 proposed fixes for this exact line and were all closed by the stale bot with no human review (#5198 had its CLA signed), so the defect is unfixed and unowned. #4837 is the only open PR touching either file; its config.py hunk is confined to is_running_in_docker() and its test hunk appends to the end of TestLazyConfig, so we share two filenames and zero changed lines.

Additional notes

  • Security: no. This only changes which boolean an empty env var yields, and it moves in the safe direction for every flag — the two that grant a bypass or extra network behaviour (SKIP_LLM_API_KEY_VERIFICATION, BROWSER_USE_CLOUD_SYNC) become harder to enable by accident, not easier.
  • I ran into this while reading the config layer, not from a production incident.
  • Disclosure: the investigation and this diff were produced by an AI coding agent working under the account owner's standing instruction to find and fix defects of this kind; the agent ran everything above on a local checkout at d8110c5 and pasted its own output. No human reviewed the diff before it was opened, and the commit carries no AI co-author trailer. Note that browser-use merges require a signed CLA, which the account owner has not yet signed — happy to do that step once it is.

Summary by cubic

Fixes #5837. Empty boolean env vars (e.g. ANONYMIZED_TELEMETRY= in a .env file or a docker-compose entry) previously parsed as True and switched telemetry, cloud sync, version checks, and other flags on; they now read False. Unset variables keep their existing defaults, and all other spellings parse exactly as before, so gate-keeping flags like SKIP_LLM_API_KEY_VERIFICATION and BROWSER_USE_CLOUD_SYNC are no longer accidentally enabled.

Refactors

  • Consolidates the six copies of the boolean env-var parse into a new _env_bool() helper.
  • Adds test_empty_boolean_env_vars_are_false, covering five of the six properties; IN_DOCKER is excluded because it ORs in is_running_in_docker().

Written for commit f8739d3. Summary will update on new commits.

View guided diff

Every boolean CONFIG property parses its env var with
`os.getenv(name, default).lower()[:1] in 'ty1'`. Substring containment makes
the empty string a match for any string, so `ANONYMIZED_TELEMETRY=` in an
.env file - or a docker-compose entry written without a value - turns
telemetry, cloud sync, version checks and the rest ON instead of off.

Test against the first character of an explicit tuple of true-ish values
instead. Unset values still fall back to each property's own default and
every other spelling behaves as before.
@CLAassistant

CLAassistant commented Sep 18, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

@mintlify

mintlify Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Preview approval required

This pull request comes from a fork, so Mintlify won't build a preview until someone with write access approves commit 6dc1744.

Approve preview

sun04222 added a commit to sun04222/browser-use that referenced this pull request Oct 23, 2026

This branch has not been deployed

No deployments
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.

Bug: an empty boolean env var switches the flag ON (ANONYMIZED_TELEMETRY= and the other five)

2 participants