Skip to content

fix: handle ValueError from formatter.parse() on malformed format strings (#733)#1030

Open
devimano2011 wants to merge 4 commits intotaverntesting:masterfrom
devimano2011:fix/733-formatter-parse-value-error
Open

fix: handle ValueError from formatter.parse() on malformed format strings (#733)#1030
devimano2011 wants to merge 4 commits intotaverntesting:masterfrom
devimano2011:fix/733-formatter-parse-value-error

Conversation

@devimano2011
Copy link
Copy Markdown
Contributor

@devimano2011 devimano2011 commented Apr 28, 2026

Fixes #733

Problem

When a string value in a test contains an unmatched { character (e.g. from an MQTT payload field like {Explanation 1), Python's string.Formatter().parse() raises a ValueError:

ValueError: expected '}' before end of string

This caused Tavern to crash with an unhandled exception instead of continuing test execution.

Fix

As suggested by @michaelboulton in the issue, wrap formatter.parse(to_format) in a try/except ValueError. When the string cannot be parsed (due to unmatched braces), log a warning and return the original string unformatted so test execution can continue.

Changes

  • tavern/_core/dict_util.py: wrap formatter.parse() in try/except ValueError in _check_and_format_values()

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Enhanced format string error handling to gracefully manage invalid syntax, preventing application errors and providing diagnostic feedback when issues occur.

…ings (taverntesting#733)

Add error handling for invalid format strings in dict_util.py
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

The _check_and_format_values function in tavern/_core/dict_util.py now includes error handling for invalid format-string syntax. When string.Formatter().parse() encounters malformed format strings, it catches the ValueError, logs a warning with the problematic string, and returns the original input unmodified instead of propagating the exception.

Changes

Cohort / File(s) Summary
Format String Error Handling
tavern/_core/dict_util.py
Added try-except wrapper around string.Formatter().parse() to gracefully handle invalid format-string syntax by emitting a warning and returning unmodified input, whilst preserving validation and formatting behaviour for valid format strings.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: handling a ValueError from formatter.parse() on malformed format strings, directly addressing the issue referenced.
Linked Issues check ✅ Passed The PR implements the required fix from issue #733: catching ValueError from formatter.parse(), logging a warning, and returning the unmodified string to allow test execution to continue gracefully.
Out of Scope Changes check ✅ Passed The changes are narrowly focused on the specific issue in dict_util.py's _check_and_format_values() function with no extraneous modifications beyond the required error handling.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tavern/_core/dict_util.py`:
- Around line 48-56: The _attempt_find_include() path must be protected the same
way as _check_and_format_values(): wrap the call to formatter.parse(to_format)
inside a try/except that catches ValueError, logs a warning (same message style
used in the existing block) and returns the original to_format (or otherwise
skip include processing) instead of allowing the exception to propagate;
refactor or extract the guarded-parse logic into a small helper used by both
_check_and_format_values() and _attempt_find_include() so both call the safe
parse routine rather than calling formatter.parse(...) directly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 25effe64-e8cb-4cc4-ad35-113b3da0d6b6

📥 Commits

Reviewing files that changed from the base of the PR and between 55e5925 and 385add0.

📒 Files selected for processing (1)
  • tavern/_core/dict_util.py

Comment thread tavern/_core/dict_util.py Outdated
Comment on lines +48 to +56
try:
would_format = list(formatter.parse(to_format))
except ValueError:
logger.warning(
"Could not parse format string '%s' - string contains invalid format syntax "
"(e.g. unmatched '{' or '}'). Returning string unformatted.",
to_format,
)
return to_format
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Also guard the !include parse path.

This try/except fixes _check_and_format_values(), but _attempt_find_include() still does a bare formatter.parse(to_format) on Line 103. A malformed string can still raise ValueError there and crash the run, so the fix is only partial. Consider reusing the same guarded parse logic in both code paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tavern/_core/dict_util.py` around lines 48 - 56, The _attempt_find_include()
path must be protected the same way as _check_and_format_values(): wrap the call
to formatter.parse(to_format) inside a try/except that catches ValueError, logs
a warning (same message style used in the existing block) and returns the
original to_format (or otherwise skip include processing) instead of allowing
the exception to propagate; refactor or extract the guarded-parse logic into a
small helper used by both _check_and_format_values() and _attempt_find_include()
so both call the safe parse routine rather than calling formatter.parse(...)
directly.

…ValueError

Add error handling for string formatting in dict_util.py
…lers

Added a helper function to safely parse format strings, improving error handling for invalid syntax.
Copy link
Copy Markdown
Member

@michaelboulton michaelboulton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't silently fail and send None, this would be very undesirable in the case where, for example, someone is trying to PATCH a field on an object and it sends null and wipes out a field instead of setting it.
If anything it should catch the ValueError and re-raise a specific tavern exception mentioning the unmatched curl brace.

…urning None

Removed the _safe_parse_format_string function and integrated its logic directly into _check_and_format_values and another function, improving error handling for format strings.
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.

Parsing Error

2 participants