Repository navigation
fix(cli): exit cleanly when gym eval submit gets a missing or invalid --config - #3445
Merged
yaoyu-33 merged 3 commits intoSep 17, 2026
Merged
Conversation
β¦id --config `_eval_submit` handed `--config` straight to Hydra `compose` and then to `SubmitConfig.model_validate` without guarding either step. A path that does not exist therefore died with a `MissingConfigException` traceback, and a file with the wrong shape leaked a raw pydantic `ValidationError` traceback, because `_handle_pydantic_validation_error` only recognises `BaseNeMoGymCLIConfig` subclasses and `SubmitConfig` is an orchestration model. Every other `--config` consumer reports both mistakes as a single `Error:` line and exit 1. - Wrap `_eval_submit` in `exit_cleanly_on_config_error` and check that the path is a file before Hydra sees it, raising a `ConfigError` that names the path. - Render `SubmitConfig` validation errors as a `ConfigError` naming the file, with the same "missing required configuration: ..." wording the generic handler uses; the field formatting is extracted into a shared `_describe_validation_errors` so both paths stay identical. Fixes NVIDIA-NeMo#2688 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tsvetan (Sven) Rankov <tsvetan.rankov@gmail.com>
sven-rankov
force-pushed
the
fix-2688-eval-submit-config-errors
branch
from
September 16, 2026 20:37
fbce1a6 to
f82b4e9
Compare
sven-rankov
marked this pull request as ready for review
September 16, 2026 20:50
yaoyu-33
previously approved these changes
Sep 17, 2026
Keep the single-use validation error translation in _eval_submit while preserving the shared field formatter and CLI error contract. Validation: 291 CLI/orchestration tests passed; 31 eval-submit tests rerun after formatting; pre-commit run --all-files passed. Model rollouts: N/A for behavior-preserving CLI refactor. Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
yaoyu-33
approved these changes
Sep 17, 2026
yaoyu-33
left a comment
Contributor
There was a problem hiding this comment.
LGTM. The single-use validation wrapper is now inlined, preserving the shared formatter and CLI error behavior. 291 CLI/orchestration tests and pre-commit run --all-files passed; the 31 submit tests were also rerun after formatting. Model rollouts are N/A for this CLI-only change; full CI remains pending.
Contributor
|
/ok to test a407938 |
Contributor
|
π Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/35248985180 |
This branch was previously deployed
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.
What does this PR do?
Fixes #2688 (
[VDR][v0.6.0] CLI-8c0bb15d).gym eval submit --config Xwas the only--configconsumer that let user mistakes escape as Python tracebacks:composewith a ~60-lineMissingConfigExceptiontraceback whose search-path dump never names the offending path;pydantic_core.ValidationErrortraceback, because_handle_pydantic_validation_erroronly recognisesBaseNeMoGymCLIConfigsubclasses andSubmitConfigis an orchestration model.Changes
_eval_submitis wrapped inexit_cleanly_on_config_error(the decorator every othergym env/gym evalcommand already uses) and checksPath(args.config).is_file()before Hydra sees the path, raising aConfigErrorthat names it.SubmitConfigvalidation errors are rendered as aConfigErrornaming the file, with the samemissing required configuration: .../invalid configuration: path (reason)wording as the generic handler. The field formatting is extracted from_handle_pydantic_validation_errorinto a shared_describe_validation_errors(pure move, no behaviour change) so the two paths cannot drift.I went with rendering the error inside
_eval_submitrather than the issue's alternative of makingSubmitConfigaBaseNeMoGymCLIConfig: that base class carries asys.argv-sniffing--helpvalidator that does not belong on an orchestration model, and the generic handler's+key=<value>hint would be misleading when the fields live in a YAML file.Before / after
Same inputs,
--dry-run, onmain(787ac2b) vs this branch. Exit code is 1 in every error case both before and after; only the output changes.1.
--configpoints at a file that does not exist (the issue's first case)Before β 80 lines:
After β 1 line:
(A directory passed as
--configgets the same treatment:... is a directory, not a file.)2.
--configexists but is not a submit config (the issue's second case)Before β 41 lines:
After β 1 line:
Errors deeper in the schema keep their location, e.g.
invalid configuration: job.output_path (Input should be a valid string), andSubmitConfig's own cross-field@model_validatorfailures render the same way (<config> (Value error, driver.policy_model 'nope' does not match any service (svc).)) instead of a traceback that echoes the whole config. A valid config produces byte-identical--dry-runoutput before and after.Testing
tests/unit_tests/test_cli_eval_submit.py: newTestEvalSubmitConfigFileErrors(missing file, directory, wrong shape, nested dotted path, cross-field@model_validator) plus twomain()-level tests asserting exit 1, theError:line, and no traceback.test_typo_in_top_level_key_is_rejectednow asserts theConfigError(and names the rejected key) instead of the rawValidationErrorthat was the bug.mainwithout the source change and pass with it.pytest tests/unit_tests/ -m "not sandbox": 4138 passed.pre-commit runon the changed files: clean.--dry-runagainst a valid config) as above.Out of scope / follow-up
While reproducing I found that
compose()bypasses the compact error rendering that@hydra.main'srun_and_reportgives every other command, soeval submitalso tracebacks on a.ymlextension, malformed YAML, a missingdefaults:group file, a non-mapping file, a bad override, and an unresolvable interpolation. Those are one root cause and deserve their own issue rather than widening this PR; I can open it with reproductions if that is useful.Checklist
pre-commit run --all-files) (so CI lint/format/copyright pass).git commit -s) (so the DCO check passes).