Fix: reject a non-positive GkeCodeExecutor timeout - #198
Open
AmaadMartin wants to merge 2 commits into
Open
Conversation
added 2 commits
August 9, 2026 13:02
`GkeCodeExecutor.timeout_seconds` had no lower bound. It is the only thing that bounds the watch for a submitted Job, because the Job carries no `active_deadline_seconds`. A value of `0` reaches the Kubernetes watch as "no timeout supplied", so the API server applies its own much larger default and the `did not complete within 0s` error names a deadline that was never applied. A negative value is meaningless as a deadline. The field now mirrors `ContainerCodeExecutor`: `Field(default=300, gt=0)`. Behavioural change: constructing with `0` or a negative value now raises `pydantic.ValidationError`. The default stays 300 and positive values are unaffected.
Correct the attribution in the field docstring: the generated Kubernetes client guards on `is not None`, so it does put `timeoutSeconds=0` on the wire. The API server, not the client, reads that zero as "no timeout". Drop the sentences that restate the `gt=0` constraint or point at a private method. Add `None` to the rejection test, so the docstring's claim that `None` is rejected is pinned. This matches `test_container_code_executor.py`.
This was referenced Aug 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
N/A
Problem:
GkeCodeExecutor.timeout_secondsaccepts0and negative values. That field is the only bound on the wait for a submitted Job, because the Job carries noactive_deadline_seconds. A0does reach the watch request astimeoutSeconds=0, but the API server reads that as no timeout and applies its own default, so the executor then reportsJob '...' did not complete within 0s.— a deadline that was never applied. A negative value is meaningless as a deadline.Solution: The field is now
Field(default=300, gt=0), so pydantic refuses a non-positive value at construction. This mirrorsContainerCodeExecutor, which already declares the same constraint. I used pydantic's own constraint instead of afield_validatorbecause a numeric bound needs no custom code. Behavioural change:GkeCodeExecutor(timeout_seconds=0)and negative values now raisepydantic.ValidationError; the default stays300and positive values are unchanged.Collision check: I listed the 100 open PRs on this fork and read the file list of every code-executor PR (100, 101, 106, 130, 132, 154, 157, 162, 164, 165, 174, 181). None touches
gke_code_executor.py, and no branch on the fork carries this change.Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.
uv run pytest tests/unittests/code_executors/test_gke_code_executor.py -q— 20 passed (17 existing, 3 new parametrized cases:0,-1,None). No existing test changed.Mutation check: I replaced the new declaration with the old
timeout_seconds: int = 300and re-ran the new test. The0and-1cases failed withFailed: DID NOT RAISE ValidationError, so they pin the new constraint. TheNonecase still passed, because the bareintannotation already rejects it; it pins the narrowing the field docstring claims, and matchestest_container_code_executor.py.Coverage: the changed line is one field declaration and adds no branch.
--cov --cov-branchreports it covered; the file total of 89% comes from pre-existing untested execution paths.Checks:
uv run mypy src/google/adk/code_executors/gke_code_executor.pyreports no issues.pre-commit run --files <both files>passes isort, pyink, ruff and the license check.Manual End-to-End (E2E) Tests:
No cluster is needed, because validation runs before any Kubernetes client is built. With
uv sync --all-extrasand no kubeconfig:Each value prints
Input should be greater than 0. A positive value passes validation and moves on to loading the kubeconfig.CI state: all Unit Tests, A2A Tests and Mypy jobs pass. The Pre-commit Linter fails only on the
update-constraintshook, which regeneratesconstraints-3.*.txtfrom today's date. That hook fails the same way onmainat my base commit352d11d3, and it touches no file in this diff.Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.