Skip to content

fix(query): read 1e6 in the run-end ceiling the way the CLI reads it - #1370

Open
v0ropaev wants to merge 1 commit into
anthropics:mainfrom
v0ropaev:fix/run-end-ceiling-scientific
Open

v0ropaev wants to merge 1 commit into
anthropics:mainfrom
v0ropaev:fix/run-end-ceiling-scientific

Conversation

@v0ropaev

@v0ropaev v0ropaev commented Oct 7, 2026

Copy link
Copy Markdown

Fixes #1359.

run_end_ceiling_ms parsed the environment value with int(), so a spelling the CLI accepts fell through to the SDK default:

run_end_ceiling_ms({"CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS": "1e6"})
# 600000, expected 1000000
run_end_ceiling_ms({"CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS": "1e2"})
# 600000, expected 100

Taking option 1 from the issue, since the docstring already said the value is read "as the CLI will see it" and named 1e6 as a spelling the CLI reads.

The parse keeps int() first and only falls back to a float read when that fails. That way everything the plain read already handled stays byte-for-byte unchanged rather than by my re-deriving it: whitespace around an integer, 0, negatives, and an integer beyond float range, which keeps its exact value and gets clamped later by the sleeper instead of becoming an infinity here. A non-finite value falls back to the default.

The six cases from your list, before and after:

value before after
1e6 600000 1000000
1e2 600000 100
-1e3 600000 600000
inf / nan 600000 600000
"9" * 400 exact integer exact integer
0, " 250 ", soon, "", -1 unchanged unchanged

Tested: six parameters added to TestRunEndCeilingFromEnv.test_parse as you suggested. Two of them fail on main (scientific, scientific_small); the other four are controls that pass either way, which is what makes them worth having. Full suite 1593 passed, 6 skipped. ruff check, ruff format --check and mypy src/ clean.

One judgement call worth flagging, since the issue leaves it open: a non-integral value like 1.5 now truncates to 1 rather than falling back. Milliseconds are integral and truncation is what a float ceiling means downstream, but if you would rather have 1.5 keep falling back to the default, say so and I will require the float to be integral.

Not run: nothing end to end. The value only bounds Query._arm_run_end_ceiling's wait, and the function is pure, so the parametrised test covers what changed.

run_end_ceiling_ms parsed the environment value with int(), so a spelling the
CLI accepts fell through to the SDK default instead:

    run_end_ceiling_ms({"CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS": "1e6"})
    600000   # expected 1000000

The docstring already said the value is read "as the CLI will see it" and
named 1e6 as a spelling the CLI reads, so the two disagreed about the same
environment variable, and the SDK closed stdin earlier or later than the
caller configured.

Keep int() first and only fall back to a float read, so everything the plain
read already handled is untouched by construction: whitespace, 0, negatives,
and an integer too large for a float, which keeps its exact value and is
clamped later by the sleeper rather than becoming an infinity here. A
non-finite value falls back to the default.

Fixes anthropics#1359

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

1 participant