Skip to content

fix(tbench2_env): treat a nan or inf reward.txt as no verdict - #1570

Open
zuraiz-anjum wants to merge 1 commit into
openenv:mainfrom
zuraiz-anjum:fix-tbench2-non-finite-reward
Open

zuraiz-anjum wants to merge 1 commit into
openenv:mainfrom
zuraiz-anjum:fix-tbench2-non-finite-reward

Conversation

@zuraiz-anjum

@zuraiz-anjum zuraiz-anjum commented Nov 6, 2026 •

Copy link
Copy Markdown

Summary

_parse_canonical_reward in tbench2_env returns None for an empty or non-numeric reward.txt, and the callers raise so the episode is reported as a scoring error. But float() also accepts nan, inf and -inf, so a reward.txt holding one of those went through as the reward. This makes a value that is not finite count as no verdict too.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • New environment
  • Refactoring

Alignment Checklist

Before submitting, verify:

  • I have read .claude/docs/PRINCIPLES.md and this PR aligns with our principles
  • I have checked .claude/docs/INVARIANTS.md and no invariants are violated
  • I have run /pre-submit-pr (or bash .claude/hooks/lint.sh and tests) and addressed all issues

RFC Status

  • Not required (bug fix, docs, minor refactoring)
  • RFC exists: #___
  • RFC needed (will create before merge)

Details

Since #1025, a missing verdict raises in _require_canonical_verdict, so RL consumers can drop the episode instead of training on a false 0.0. On main, __TB2_REWARD__:nan is parsed as float("nan"), _evaluate_task and _evaluate_docker return reward=nan with tests_passed: False, and the NaN goes to the trainer. inf goes through the same way.

The other envs that read a reward file already reject this case: _parse_reward_override in coding_tools_env, jupyter_env and terminus_env returns no reward when math.isfinite(value) is false. This applies the same check in _parse_canonical_reward, so both the local and the Docker path raise "canonical harness produced no verdict", the same as for an empty reward.txt. I also updated the docstring.

Test Plan

Two tests in tests/envs/test_tbench2_env.py, next to the missing-verdict tests from #1025:

  • test_evaluate_non_finite_verdict_raises, for nan, inf and -inf on the local path. It also checks that the staged tests and the verifier dir are still wiped.
  • test_evaluate_docker_non_finite_verdict_raises for nan on the Docker path, with the fake container.

Run with PYTHONPATH=src:envs pytest tests/envs/test_tbench2_env.py:

  • main with only the new tests: the 4 new cases fail (DID NOT RAISE), the existing verdict tests pass.
  • this branch: the 4 cases pass and nothing else changes.

The three checks from .claude/hooks/lint.sh (usort check, ruff format --check, ruff check) are clean on the files this PR touches; the findings a tree-wide run reports are in other files and are the same on main.


Note

Low Risk
Scoring-path guard only; finite rewards unchanged. Low blast radius—errors instead of NaN/inf rewards.

Overview
Canonical TB2 reward parsing now treats nan, inf, and -inf in the verifier marker line as no verdict (None), not a valid score—float() accepts those strings, so they used to propagate to the trainer.

The docstring on _parse_canonical_reward was updated to match. Tests cover withheld local evaluate for all three non-finite strings (staging still wiped) and Docker evaluate with a nan marker, both expecting the same RuntimeError as an empty or missing verdict.

Reviewed by Cursor Bugbot for commit f6c2840. Bugbot is set up for automated code reviews on this repo. Configure here.

_parse_canonical_reward returns None for an empty or non-numeric
reward.txt, and the callers raise so the episode is reported as a
scoring error instead of a reward. float() also accepts "nan", "inf"
and "-inf", so those values went through as the reward, and a NaN or
infinite reward reached the trainer.

Return None for a value that is not finite, the same rule the
coding_tools, jupyter and terminus envs already apply to their reward
files. Tests cover the local and the Docker evaluate paths.

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.

1 participant