You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tracing crashes with UnicodeEncodeError on surrogate escapes in hook arguments/results #681
When pluggy tracing is enabled (e.g. pytest's --debug flag), hook arguments or return values containing surrogate escape characters (like \ud800) cause a UnicodeEncodeError crash. This is because _format_message in _tracing.py uses str() to format values, and the resulting string with literal surrogates cannot be written to most output targets.
_format_message currently formats two kinds of data identically using str():
Structural labels passed as positional args — e.g. "finish", "-->", hook names — which are always safe ASCII strings
Python values — hook kwargs values (rendered via the extra dict) and hook return values — which may contain arbitrary data including surrogates
The fix needs to apply repr() only to the value positions, not to structural labels.
Intended Solution
In _tracing.py line 38 — use {value!r} for the extra/kwargs dict values:
lines.append(f"{indent}{name}: {value!r}\n")
This makes kwargs values in trace output show their type (e.g. 'lfplugin' instead of lfplugin, PosixPath('/foo') instead of /foo) and safely escapes surrogates.
In _manager.py line 506 — use repr() on the hook result before passing it as a trace arg:
This ensures the result value is safely formatted, while "finish", hook_name, and "-->" remain plain str()-formatted (via _format_message's existing map(str, args)).
Do NOT change the content = " ".join(map(str, args)) line in _format_message. Keeping str() there preserves readable structural output without quoting labels. The caller (_manager.py) is responsible for pre-formatting any unsafe values with repr().
This avoids the double-repr problem and keeps trace output readable:
I reproduced both failure paths on current main (cba86ad): a surrogate in a traced kwargs value and a surrogate in a traced hook result both leave a literal surrogate in the formatted message and fail under UTF-8 encoding.
I am working on the intended scoped solution described here: !r for values in the trailing kwargs mapping, and repr() for the result passed by PluginManager.enable_tracing(), with regression coverage for both paths. I will run the full test suite and pre-commit checks locally.
I am using Codex as an implementation assistant; I will review and take responsibility for the change and any follow-up.
Hi, I’d like to investigate the tracing UnicodeEncodeError with surrogate escapes. I can add a small regression test using the affected hook arguments and then keep the fix isolated to trace formatting. Is this still available for a community contribution?
Activity
almondsun commentedon Jul 21, 2026
I reproduced both failure paths on current
main(cba86ad): a surrogate in a traced kwargs value and a surrogate in a traced hook result both leave a literal surrogate in the formatted message and fail under UTF-8 encoding.I am working on the intended scoped solution described here:
!rfor values in the trailing kwargs mapping, andrepr()for the result passed byPluginManager.enable_tracing(), with regression coverage for both paths. I will run the full test suite and pre-commit checks locally.I am using Codex as an implementation assistant; I will review and take responsibility for the change and any follow-up.
Gambit-Checkmate commentedon Aug 22, 2026
Hi, I’d like to investigate the tracing UnicodeEncodeError with surrogate escapes. I can add a small regression test using the affected hook arguments and then keep the fix isolated to trace formatting. Is this still available for a community contribution?
Keep trace output str-based
Keep trace output str-based
Make hook tracing defensive about repr and surrogates
Keep trace output str-based
Make hook tracing defensive about repr and surrogates
Keep trace output str-based
Make hook tracing defensive about repr and surrogates
Keep trace output str-based