Skip to content

fix: parse integral scientific notation in CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS - #1362

Open
azmi2409 wants to merge 2 commits into
anthropics:mainfrom
azmi2409:fix/run-end-ceiling-scientific-notation
Open

azmi2409 wants to merge 2 commits into
anthropics:mainfrom
azmi2409:fix/run-end-ceiling-scientific-notation

Conversation

@azmi2409

@azmi2409 azmi2409 commented Oct 6, 2026

Copy link
Copy Markdown

Fixes #1359.

run_end_ceiling_ms() parsed CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS with a
bare int(raw), so CLI-compatible scientific-notation spellings like "1e6"
were treated as invalid and silently fell back to the 600_000ms default
instead of 1_000_000.

The value is now parsed by a small _parse_run_end_ceiling_ms helper that
accepts plain integers (with surrounding whitespace, as before) plus integral
scientific-notation spellings such as 1e6, 1E6, 2.5e3. Everything else
keeps the old behavior:

  • unset / invalid strings / empty -> 600_000 default
  • "0" -> 0 (no limit)
  • negatives -> default
  • non-integral values (1.5, 1e-1) -> default
  • very large values are honored, then clamped downstream by the existing
    _MAX_RUN_END_CEILING_MS sleeper bound

The parser also guards against absurd exponents (1e999999999) so it can
never build a gigantic int.

Adds a "1e6" -> 1_000_000 regression case to
TestRunEndCeilingFromEnv.test_parse. Full suite: 1588 passed, 6 skipped;
ruff check, ruff format --check, and strict mypy are clean.

…CEILING_MS

Fixes anthropics#1359.

`run_end_ceiling_ms()` parsed `CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS` with a
bare `int(raw)`, so CLI-compatible scientific-notation spellings like `"1e6"`
were treated as invalid and silently fell back to the 600_000ms default
instead of 1_000_000.

The value is now parsed by a small `_parse_run_end_ceiling_ms` helper that
accepts plain integers (with surrounding whitespace, as before) plus integral
scientific-notation spellings such as `1e6`, `1E6`, `2.5e3`. Everything else
keeps the old behavior:

- unset / invalid strings / empty -> 600_000 default
- `"0"` -> 0 (no limit)
- negatives -> default
- non-integral values (`1.5`, `1e-1`) -> default
- very large values are honored, then clamped downstream by the existing
  `_MAX_RUN_END_CEILING_MS` sleeper bound

The parser also guards against absurd exponents (`1e999999999`) so it can
never build a gigantic int.

Adds a `"1e6" -> 1_000_000` regression case to
`TestRunEndCeilingFromEnv.test_parse`. Full suite: 1588 passed, 6 skipped;
`ruff check`, `ruff format --check`, and strict `mypy` are clean.
@sigley

sigley commented Oct 6, 2026

Copy link
Copy Markdown

I found one boundary case in the exponent guard on the current PR head (924746e).

Running the parser from this head on Python 3.10.11 gives:

_parse_run_end_ceiling_ms("0e18") -> 0
_parse_run_end_ceiling_ms("0e19") -> 2147483647
run_end_ceiling_ms({"CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS": "0e19"}) -> 2147483647

That changes zero from the documented 0 = no limit semantics into the maximum finite sleeper ceiling solely when the exponent crosses 18. The cause looks like the shift > 18 fast path returning _MAX_RUN_END_CEILING_MS before the zero coefficient is handled.

Would it make sense to handle coefficient == 0 before that large-shift guard and add a 0e19 -> 0 regression case? That should preserve the zero semantics while keeping the bounded path for non-zero absurd exponents.

0e19 (and any 0eN) keeps the documented 0 = no-limit semantics instead
of falling into the _MAX_RUN_END_CEILING_MS fast path. Adds a 0e19 -> 0
regression case per review feedback.
@azmi2409

azmi2409 commented Oct 7, 2026

Copy link
Copy Markdown
Author

Good catch — fixed. The zero coefficient is now handled before the large-shift guard, so 0e19 (and any 0eN) keeps the documented 0 = no-limit semantics. Added a 0e19 -> 0 regression case (zero_scientific_notation_boundary) to TestRunEndCeilingFromEnv.test_parse. All 10 tests in the class pass.

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.

run_end_ceiling_ms falls back to the default for CLI-compatible 1e6 values

2 participants