Skip to main content

EnvBisect

CI Python 3.11+ MIT License

Find the environment difference that actually broke your program.

Works locally.
Fails in CI.
46 environment variables differ.
EnvBisect finds the 2 that matter in the included demo.

Install once from the checkout with python -m pip install -e ., then run:

envbisect diagnose \
  --pass examples/demo/pass.env \
  --fail examples/demo/fail.env \
  -- python examples/demo/app.py

PowerShell (one line): envbisect diagnose --pass examples/demo/pass.env --fail examples/demo/fail.env -- python examples/demo/app.py

The report includes:

46 environment differences found.
...
Minimal failure-inducing set (1-minimal under the tested conditions):
  FEATURE_CACHE
    0 → 1
  TZ
    Asia/Kolkata → UTC
These changes act together in the observed failure.

Neither change causes this demo failure alone; both are required. The 44 DEMO_NOISE_* changes do nothing.

An environment diff tells you what changed. EnvBisect tests which combinations reproduce the failure under a specified command and execution environment.

Install

Requires Python 3.11 or newer. From a checkout:

python -m pip install -e .
envbisect --help

There are no required runtime dependencies. You can also run python -m envbisect from the checkout.

Diagnose your command

Create two dotenv snapshots. The passing snapshot describes the environment in which the command succeeds; the failing snapshot describes the one in which it fails.

# working.env
TZ=Asia/Kolkata
FEATURE_CACHE=0
# broken.env
TZ=UTC
FEATURE_CACHE=1

Run the same command against both snapshots:

envbisect diagnose --pass working.env --fail broken.env -- python your_script.py

Everything after -- is the command and its arguments. To use shell expansion, pipes, or shell builtins, invoke a shell explicitly as that command. EnvBisect runs each candidate in a subprocess and treats exit code 0 as PASS and a nonzero exit code as FAIL.

EnvBisect identifies the snapshot differences, then confirms that the command passes with --pass and fails with --fail. It stops with a clear message if these baselines disagree with the labels. It minimizes the failure-inducing changes and verifies the result. A typical successful report contains:

46 environment differences found.

Minimal failure-inducing set (1-minimal under the tested conditions):
  FEATURE_CACHE
    0 → 1
  TZ
    Asia/Kolkata → UTC

Verification
  PASS + changes → FAIL 5/5
  FAIL - changes → PASS 5/5

Runs: 46

The example run count is for this deterministic fixture with the default repeat count; other commands and settings can require a different number of executions. The actual report also shows elapsed time.

Snapshot semantics

EnvBisect captures the current process environment once. For each experiment it copies that environment, removes every key mentioned in either dotenv file, and applies the chosen snapshot's values. Keys absent from both files remain inherited from the captured host environment. A key present in only one file is absent from the other snapshot, even if that key was present in the host environment.

This makes small snapshots usable while preserving an executable search path and other host settings. Run both baselines on the same machine and keep inputs outside the snapshots stable. EnvBisect never edits the snapshot files or your permanent environment.

Dotenv files support assignments such as KEY=value, empty values (KEY=), comments, whitespace, and quoted values. Missing and empty values have different meanings.

Why minimization matters

Suppose the passing environment has A=0 and B=0, while the failing one has A=1 and B=1:

Changes applied to the passing snapshot Command
Neither PASS
A only PASS
B only PASS
A and B FAIL

Checking each variable alone misses this case. EnvBisect uses a ddmin style algorithm that tests subsets and complements of the differing changes. The resulting set is 1-minimal for the observed behavior: removing any one selected change no longer reproduces the failure. It is not a guarantee of the smallest possible set by cardinality or a unique root cause. See How it works.

Reliability and output

EnvBisect uses three runs per baseline and candidate by default, and at least five runs for final verification. Repeated execution helps expose unstable commands:

envbisect diagnose --pass working.env --fail broken.env --repeats 3 --timeout 30 -- python your_script.py

For a repeated candidate, unanimous zero exits mean PASS; unanimous nonzero exits mean FAIL; mixed outcomes are FLAKY. A timeout is reported separately. If outcomes do not support a reliable minimization, EnvBisect reports uncertainty instead of claiming a cause.

Use --verbose to inspect command output, --quiet to print only identified keys on success, and --no-color for plain terminals. Quiet and color settings do not change classification.

Variable names suggesting secrets, including tokens, passwords, credentials, auth data, private keys, and API keys, have their values redacted in reports. Real values still reach the tested command. Redaction is heuristic: review snapshots before sharing them, and remember that a command can itself print secrets to stdout or stderr, especially in verbose mode.

Exit codes

Code Meaning
0 Diagnosis and verification completed
1 Invalid usage or configuration
2 Baselines do not match PASS/FAIL expectations
3 No differing environment variables
4 Flaky, timed out, or otherwise indeterminate evidence
5 Command execution or internal error

Limits of the conclusion

A diagnosis is a minimal failure-inducing set under the tested environment and command. Other causes may exist. Files, network responses, time, process state, external services, and the inherited host environment can change outcomes independently of the dotenv differences. Side effects from one run can affect later runs. A command that is flaky or whose behavior changes over time may not admit a trustworthy result.

EnvBisect diagnoses environment-variable values and presence in two snapshots. It does not inspect dependency versions, the filesystem, containers, or network behavior.

Development

python -m pip install -e ".[dev]"
python -m pytest
python -m ruff check .
python -m ruff format --check .

See Contributing for the project workflow, demo recording instructions, the changelog, and the v0.1.0 release notes. Future work will stay focused on making experiments and explanations more reliable before adding other kinds of environment drift.

License

EnvBisect is available under the MIT License.

Release files for envbisect 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for envbisect 0.1.0
File Size Uploaded
envbisect-0.1.0.tar.gz 32.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for envbisect 0.1.0
File Interpreter ABI Platform
envbisect-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 52.9 kB

Release files / envbisect-0.1.0.tar.gz

Download URL envbisect-0.1.0.tar.gz
Size 32.8 kB
Tags Source
SHA-256 checksum
How to use checksums
a2a341946e4573a27318090f4edbb0911f55cf37d90abe65ef77a98e71d4873f
BLAKE2b-256 checksum
How to use checksums
2ba0af24e52371a8ac2e621bc083db588361cd534a1c2500414eea6e48be2cdc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.0

Release files / envbisect-0.1.0-py3-none-any.whl

Download URL envbisect-0.1.0-py3-none-any.whl
Size 20.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0a705a6a3646370758bd948512dd4239404c098dbc5caeb9ca061d07f068a70
BLAKE2b-256 checksum
How to use checksums
288176233797dea399e41aa00b22004e3fabfdd7918147c73637de846c42e950
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.0

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page