Skip to content

openclaw plugin: session_start/cron events permanently stuck in retry queue (422, not transient) #1042

Description

@pinzo

Summary

The OpenClaw plugin's local retry queue (event_queue.jsonl) can get permanently stuck: it retries failed events indefinitely, but two of the payloads it sends are structurally invalid against the backend's own validation, so retries can never succeed. stash status then reports health: "failing" forever for events that will never sync.

Repro

  1. Install the OpenClaw plugin and let an agent run a cron/scheduled session. OpenClaw builds session keys for scheduled runs like agent:<name>:cron:<uuid>:run:<timestamp>, which is routinely >64 chars.
  2. POST /api/v1/me/sessions/events rejects it:
    curl -X POST http://localhost:3456/api/v1/me/sessions/events \
      -H "content-type: application/json" -H "authorization: Bearer $API_KEY" \
      -d '{"agent_name":"robert","event_type":"session_start","content":"","session_id":"agent:athena:cron:3745fb17-d237-4ae6-bfde-bf5f1ee820a1:run:1786521600019","metadata":{}}'
    
    422 {"detail":[
      {"type":"string_too_short","loc":["body","content"],"msg":"String should have at least 1 character", ...},
      {"type":"string_too_long","loc":["body","session_id"],"msg":"String should have at most 64 characters", ...}
    ]}
    
  3. This request now sits in ~/.stash/plugins/openclaw/event_queue.jsonl forever. drainQueue() in plugins/openclaw-plugin re-POSTs the exact same (still-invalid) payload on every future successful event, gets the same 422 every time, and re-appends it to the queue — it can never self-heal.

Two separate root causes

  1. session_id length: the OpenClaw plugin's session_start/before_message_write handlers pass through OpenClaw's own session key unmodified. Scheduled/cron session keys routinely exceed the backend's 64-char cap on session_id.
  2. session_start always sends content: "" (plugins/openclaw-plugin/index.ts, the session_start handler), but the backend requires content to be at least 1 character. So every session_start event is permanently unsyncable, not just cron ones — it's just low-volume for long-lived sessions that rarely re-fire session_start.

Suggested fix

  • Truncate/hash long session_ids client-side before sending (or relax the backend's max length), and
  • send a non-empty placeholder for session_start content (e.g. "[session started]") instead of "".

Impact

Low severity — no real conversational content is lost (only session markers / cron heartbeat messages hit this), but stash status permanently reports health: "failing" for a condition that can never be resolved by retrying, which undermines it as a signal for genuine upload problems.

Happy to send a PR for the two-line fix if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions