iflytek/astron-agent · error · CustomException

23901

23901

Error message

Conversation is running, please do not resume repeatedly

What it means

Raised by resume_open when EventRegistry().check_event_lock(event_id) is true, i.e. another request (span sid) already holds the lock for this event and it is currently being processed. The lock prevents concurrent resumes of the same conversation; a second resume attempt fails with code 23901 (EVENT_REGISTRY_LOCK_ERROR).

Solutions

  1. Check the conversation state client-side and disable the resume action while a resume/stream is in flight.
  2. Wait for the running resume to finish (consume the SSE stream to completion) before retrying.
  3. Implement client-side deduplication/idempotency so only one resume request per event is sent.
  4. If a lock is stuck (holder crashed), wait for lock expiry or clear it via unlock_event once the holder is confirmed dead.

Example fix

# before
await Promise.all([resume_open(event_id), resume_open(event_id)])

# after
if (!resumingRef.current) {
  resumingRef.current = true
  try {
    await resume_open(event_id)
  } finally {
    resumingRef.current = false
  }
}
Defensive patterns

Strategy: retry

Validate before calling

if EventRegistry().check_event_lock(event_id=event_id):
    raise RuntimeError(f"event {event_id} is locked; resume already in progress")

Type guard

def is_unlocked(event_id: str) -> bool:
    return not EventRegistry().check_event_lock(event_id=event_id)

Try / catch

try:
    await resume_open(event_id=event_id)
except CustomException as e:
    if e.code == CodeEnum.EVENT_REGISTRY_LOCK_ERROR.code:
        await asyncio.sleep(backoff)
        # retry once, or surface 'resume in progress' to the user
    else:
        raise

Prevention

When it happens

Trigger: Two resume calls racing on the same event_id (double-click, retry timeout, parallel tabs); a previous resume still running/streaming its response while the client reissues resume.

Common situations: User clicks 'continue' repeatedly in the UI; HTTP client retries after a slow first resume; frontend ignores the still-open SSE stream and fires another resume; background job and user request both resume the same event.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/22e0523c60f7204c. Report an issue: GitHub.

Appendix: source

Thrown at core/workflow/api/v1/chat/open.py:131

    event_id = request.event_id
    event_type = request.event_type
    content = request.content
    span = Span(app_id="", uid="", chat_id="")
    m = Meter()

    with span.start(
        attributes={"event_id": event_id},
    ) as span_context:

        try:
            event: Optional[Event] = EventRegistry().get_event(event_id=event_id)
            if event is None:
                raise CustomException(
                    CodeEnum.EVENT_REGISTRY_NOT_FOUND_ERROR,
                    "Event not found",
                )
            if EventRegistry().check_event_lock(event_id=event_id):
                raise CustomException(CodeEnum.EVENT_REGISTRY_LOCK_ERROR)
            EventRegistry().lock_event(event_id=event_id, sid=span.sid)

            m.set_label("flow_id", event.flow_id)
            m.set_label("app_id", event.app_id)

            span.set_attribute("flow_id", event.flow_id)
            span.app_id = event.app_id
            span.uid = event.uid
            span.chat_id = event.chat_id

            await span_context.add_info_events_async(
                {"resume_event": json.dumps(event.dict(), ensure_ascii=False)}
            )

            if not event.status == ChatStatus.INTERRUPT.value:
                raise CustomException(
                    CodeEnum.EVENT_REGISTRY_NOT_FOUND_ERROR,
                    "Current event is not paused",

View on GitHub (pinned to 5e758547a8)