[core] fix: wrap TQ write in try-except to prevent training hang on write failure#81
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates _short_failure_reason to include the exception class name in the returned string and wraps the _write_session_trajectories_to_tq call in a try-except block to handle and log write failures. The review comments suggest avoiding redundant class names when the exception message is empty and using the _short_failure_reason helper when appending TQ write errors to failure_reasons.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| message = str(error) | ||
| if not message: | ||
| message = error.__class__.__name__ | ||
| return message[:512] | ||
| return f"{error.__class__.__name__}:{message}"[:512] |
There was a problem hiding this comment.
If the exception message is empty (e.g., for a generic exception without a message), message is set to error.__class__.__name__. This results in a redundant return value of ClassName:ClassName (e.g., ValueError:ValueError). We can simplify this by returning just the class name when the message is empty.
| message = str(error) | |
| if not message: | |
| message = error.__class__.__name__ | |
| return message[:512] | |
| return f"{error.__class__.__name__}:{message}"[:512] | |
| message = str(error) | |
| if not message: | |
| return error.__class__.__name__[:512] | |
| return f"{error.__class__.__name__}:{message}"[:512] |
| except Exception as e: | ||
| logger.exception(f"TQ write failed for uid={uid} session={session_index}: {e}") | ||
| failed_sessions += 1 | ||
| failure_reasons.append(f"TQ write error: {e}") |
There was a problem hiding this comment.
Since the goal of this PR is to include the exception class name in the failure reasons for easier debugging, we should use the _short_failure_reason helper here as well. Otherwise, f"TQ write error: {e}" will still lose the exception class name (e.g., producing TQ write error: 'finish_reason' instead of TQ write error: KeyError:'finish_reason').
| except Exception as e: | |
| logger.exception(f"TQ write failed for uid={uid} session={session_index}: {e}") | |
| failed_sessions += 1 | |
| failure_reasons.append(f"TQ write error: {e}") | |
| except Exception as e: | |
| logger.exception(f"TQ write failed for uid={uid} session={session_index}: {e}") | |
| failed_sessions += 1 | |
| failure_reasons.append(f"TQ write error: {_short_failure_reason(e)}") |
What does this PR do?
Description
Problem
When _write_session_trajectories_to_tq raises an exception during TransferQueue write (e.g., KeyError if required fields like finish_reason are missing from the trajectory), the exception propagates out of _run_prompt_sessions_to_tq before it can update the prompt's status in TQ ("finished" / "failure").
This leaves the prompt permanently in "pending" state, causing _has_enough_samples in the replay buffer to never reach batch_size. The training loop hangs indefinitely, with no visible error other than a cryptic failure_reason: "'finish_reason'" in the logs (which loses the exception class name).
Root cause flow
Checklist Before Starting
[{modules}] {type}: {description}(checked by CI){modules}may includecore,interaction,model,env,tools,deployment,reward,dashboard,docs,examples,data,train,ci,build,deps,misc,like[interaction, tools, docs]{type}must be one offeat,fix,refactor,chore,test[BREAKING]to the beginning of the title[1/N][BREAKING][deployment, docs] feat: simplify runtime env configurationTest
Defense against abnormal scenarios.
API and Usage Example
N/A
Design & Code Changes
Fix
failure_reasons. Move success_sessions and success_outputs to the else branch so they only increment on successful TQ write.
This ensures:
Checklist Before Submitting
pre-commit install && pre-commit run --all-files --show-diff-on-failure --color=always