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
Traceback (most recent call last):
File "/Users/nigelstuke/.local/bin/serena-hooks", line 10, in <module>
sys.exit(hook_commands())
~~~~~~~~~~~~~^^
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/click/core.py", line 1524, in __call__
return self.main(*args, **kwargs)
~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/click/core.py", line 1445, in main
rv = self.invoke(ctx)
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/click/core.py", line 1912, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/click/core.py", line 1308, in invoke
return ctx.invoke(self.callback, **ctx.params)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/click/core.py", line 877, in invoke
return callback(*args, **kwargs)
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/serena/hooks.py", line 589, in cleanup
SessionEndCleanupHook(HookClient(client)).execute()
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/Users/nigelstuke/.local/share/uv/tools/serena-agent/lib/python3.13/site-packages/serena/hooks.py", line 38, in __init__
raise ValueError("Session ID is required in the hook input data")
ValueError: Session ID is required in the hook input data
A traceback is also not valid Stop-hook JSON, so Codex reports the same class of failure.
What Codex expects
For a Stop hook, Codex expects stdout to contain a valid JSON object. The minimal successful response shape is:
{"continue": true}
Other logs or diagnostics should go to stderr or to a file, and the hook should avoid emitting non-JSON stdout.
Expected behavior
For --client=codex, serena-hooks cleanup should always produce valid Codex Stop-hook JSON on stdout, including when cleanup is a no-op or when the input is missing optional/expected fields.
For example:
{"continue": true}
If cleanup fails internally, it could still either:
emit valid JSON and log details elsewhere, or
emit a Codex-compatible blocking JSON response if there is a reason Codex should not continue.
Actual behavior
With a session_id, stdout is empty.
Without a session_id, the command raises a Python traceback.
Codex reports hook returned invalid stop hook JSON output.
Local workaround
Wrapping the command to suppress Serena's own output and explicitly emit Codex-compatible JSON avoids the error:
This is only a workaround; it would be nicer if the --client=codex hook command handled Codex's Stop-hook stdout contract directly.
Related
Claude Code hooks #1480 discusses whether cleanup belongs on Claude Code Stop vs SessionEnd. This issue is narrower: when cleanup is used as a Codex Stop hook, stdout needs to be JSON-compatible.
Summary
When
serena-hooks cleanup --client=codexis configured as a CodexStophook, Codex can report:I hit this in a real Codex session with this hook config:
{ "hooks": { "Stop": [ { "hooks": [ { "command": "serena-hooks cleanup --client=codex", "statusMessage": "Cleaning up Serena", "type": "command" } ] } ] } }This may be adjacent to #1480, but the concrete failure here is Codex-specific: the Stop hook command's stdout must be valid Stop-hook JSON.
Environment
serena-hooks cleanup --client=codexuv toolmanagedserena-agentScenario 1: realistic Codex Stop input, empty stdout
With a
session_idpresent, cleanup exits successfully but emits no stdout:Observed:
Codex expects Stop hook stdout to be a valid JSON object. Empty stdout is therefore parsed as invalid Stop-hook JSON.
For comparison, another Codex Stop hook in the same config emits:
{"continue": true}and does not trigger the JSON error.
Scenario 2: missing
session_id, Python traceback on stdout/stderrIf cleanup receives input without
session_id, it raises a Python traceback:Observed traceback:
A traceback is also not valid Stop-hook JSON, so Codex reports the same class of failure.
What Codex expects
For a
Stophook, Codex expects stdout to contain a valid JSON object. The minimal successful response shape is:{"continue": true}Other logs or diagnostics should go to stderr or to a file, and the hook should avoid emitting non-JSON stdout.
Expected behavior
For
--client=codex,serena-hooks cleanupshould always produce valid Codex Stop-hook JSON on stdout, including when cleanup is a no-op or when the input is missing optional/expected fields.For example:
{"continue": true}If cleanup fails internally, it could still either:
Actual behavior
session_id, stdout is empty.session_id, the command raises a Python traceback.hook returned invalid stop hook JSON output.Local workaround
Wrapping the command to suppress Serena's own output and explicitly emit Codex-compatible JSON avoids the error:
This is only a workaround; it would be nicer if the
--client=codexhook command handled Codex's Stop-hook stdout contract directly.Related
StopvsSessionEnd. This issue is narrower: when cleanup is used as a CodexStophook, stdout needs to be JSON-compatible.