✨ feat(config): show clean errors for type mismatches#3838
Merged
gaborbernat merged 4 commits intotox-dev:mainfrom Feb 27, 2026
Merged
✨ feat(config): show clean errors for type mismatches#3838gaborbernat merged 4 commits intotox-dev:mainfrom
gaborbernat merged 4 commits intotox-dev:mainfrom
Conversation
Config type errors in TOML (e.g. deps = [1] or a replace-if producing a nested list) previously crashed with an opaque TypeError and a full stack trace logged as "internal error" during tox run. Wrap config load failures in TomlLoader.build() as HandledError with env/key context, catch HandledError in _evaluate() so it logs cleanly instead of as "internal error", and improve PythonDeps/PythonConstraints factory messages to identify which items are invalid.
The factory error message changed from dumping the raw value to a descriptive message identifying invalid items by index and type.
Show full error details in HandledError messages instead of repr(). Add descriptive messages to all opaque TypeError raises in set_env, MemoryLoader.to_command, and MemoryLoader.to_env_list.
gaborbernat
added a commit
to gaborbernat/tox
that referenced
this pull request
Feb 27, 2026
The error message tests from tox-dev#3838 only checked partial messages or a handful of fields. This makes it hard to catch regressions where the context prefix ("failed to load <env>.<key>: ...") gets lost or where specific field types produce unhelpful errors. Adds a comprehensive parametrized test covering every user-configurable field type: str, bool, int, float, Path, list[str], set[str], list[Command], EnvList, and factory-based fields (deps, constraints). Updates existing toml_loader and req_file tests to assert the complete error message including the field context prefix.
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.
When a TOML config contains a type mismatch — for example
deps = [1], or areplace = "if"whosethenproduces a nested list like[['pkg']]— tox previously crashed with an opaqueTypeErrorand a full stack trace logged as "internal error." This made it difficult for users to understand what went wrong or how to fix their configuration.The change wraps config load failures in
TomlLoader.build()asHandledErrorwith the environment name and config key in the message (e.g.failed to load py.deps: deps expected str, list[str], or list[Requirement], got list with invalid items: [0] int), mirroring how the ini loader already handles this. The_evaluate()function in the runner now catchesHandledErrorand logs it cleanly instead of falling through to the generic "internal error" handler. Factory methods inPythonDeps,PythonConstraints, andset_envnow produce descriptive error messages that identify the expected types, the actual types found, and the offending items by index.The error handling applies to all config type mismatches, not just replacement-related ones. Any invalid value in a TOML config key will now produce a clear, actionable message without a stack trace.
Fixes #3831