fix(cron): cap session_id at 64 chars to satisfy prompt_cache_key limit - #28307
fix(cron): cap session_id at 64 chars to satisfy prompt_cache_key limit#28307wsh123098-lang wants to merge 1 commit into
Conversation
OpenAI/xAI reject prompt_cache_key > 64 chars with HTTP 400. The cron
session_id format `cron_{job_id}_{YYYYMMDD_HHMMSS}` has 21 chars of
overhead, so any job_id over 43 chars (e.g. the oneshot
'oneshot-plan-b-merge-transition-into-evaluation' at 47) blew the limit
and the job failed to run.
Truncate long job_ids to fit and append an 8-char sha1 suffix so two
truncated names with a shared prefix don't collide on the cache scope.
Short job_ids (≤43 chars) pass through unchanged.
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the focused regression fix. The premise still holds on current main: cron builds cron_{job_id}_{timestamp} without a cap in cron/scheduler.py:1487, passes it as session_id at cron/scheduler.py:1755, and the Codex transport forwards that value to prompt_cache_key in agent/transports/codex.py:159 / agent/transports/codex.py:252.
Problems
- The scheduler-side truncation needs to update the cron run-history contract too. Current main looks up a job's runs with
prefix = f"cron_{job_id}_"inhermes_state.py:2238, and the web endpoint documents the same literalcron_{job_id}_{timestamp}shape inhermes_cli/web_server.py:6827-6835. After this PR, long job ids would run, but history lookup by the original job id would miss the truncated/hash-prefixed session ids.
Suggested changes
- Reuse the same safe-id mapping in the run-history lookup, or persist an explicit cron job id on the session so lookup does not depend on the prompt-cache-safe session id string.
- Add a regression test for a long job id that verifies both the capped session id and
list_cron_job_runs(original_job_id)returning that run.
This is an automated hermes-sweeper review.
| @@ -1285,7 +1302,10 @@ def _run_job_impl(job: dict) -> tuple[bool, str, str, Optional[str]]: | |||
| logger.info("Job '%s': script produced no output, skipping AI call.", job_name) | |||
| return True, "", SILENT_MARKER, None | |||
There was a problem hiding this comment.
This keeps the prompt_cache_key under the provider limit, but it also changes the session-id prefix for long job ids. SessionDB.list_cron_job_runs() still queries cron_{original_job_id}_, so long-job runs will become undiscoverable in the cron run-history path unless that lookup uses the same mapping or an explicit job-id field.
|
Thanks for the focused cron regression fix. This is an automated hermes-sweeper review: current
This also avoids the scheduler-side session-id rewrite proposed here, preserving the existing |
What does this PR do?
Cron jobs with a job_id longer than 43 characters fail at first fire with HTTP 400 from OpenAI / xAI:
Root cause is in
cron/scheduler.py: the session id passed torun_agent(...)(and from there toprompt_cache_keyon the Responses API) is built asThe fixed
cron_+_YYYYMMDD_HHMMSSoverhead is 21 chars, leaving only 43 chars forjob_idbefore the assembled key blows past the API's 64-charprompt_cache_keycap. There is no length validation when jobs are created, and no defensive truncation at the transport layer (agent/transports/codex.pypasses the session id straight through), so a single long-named oneshot is enough to silently break.This PR truncates over-long job_ids when building the cache key, appending an 8-char sha1 suffix so two long names that share a prefix don't collide on the same cache scope. Short job_ids (≤ 43 chars) are unchanged — there is no behavior change for any existing cron job whose id fits.
Related Issue
No existing issue — I searched
prompt_cache_key,session_id length, andcron 400against the open issue list and found nothing matching.Fixes #
Type of Change
Changes Made
cron/scheduler.py:_safe_job_id_for_session(job_id)helper near_resolve_originthat truncates long job_ids to64 - len("cron__YYYYMMDD_HHMMSS") = 43chars and appends an 8-char sha1 digest for collision resistance._cron_session_idat the existing call site.import hashlib.tests/cron/test_scheduler.py:TestSafeJobIdForSessionclass with three regression tests:oneshot-plan-b-merge-transition-into-evaluation, 47 chars) yields a 43-char safe id and a final session id of exactly 64 chars.How to Test
Reproduce the bug on
main:hermes cron createwith a long--name, or any job whose auto-generated id ends up long).Verify the fix on this branch:
prompt_cache_keyis now ≤ 64 chars.Checklist
Code
fix(cron): ...)pytest tests/cron/ -qandpytest tests/cron/test_scheduler.py -k SafeJobId -vand all relevant tests pass. The broaderpytest tests/ -qrun on my machine surfaces 5 pre-existing failures intests/gateway/test_discord_*,tests/agent/test_anthropic_adapter.py, andtests/acp/test_edit_approval.pythat are unrelated to this change (they reproduce onHEAD~1without these edits; the acp failure is an env-specific/private/var/folderssensitive-path refusal).TestSafeJobIdForSession)Documentation & Housekeeping
cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
The error as observed in the wild (cron output dump):
After the fix, the corresponding
prompt_cache_keyis 64 chars exactly: