Skip to content

Fix OpenCode session-start race when session.created fires twice #883

@sanogueralorenzo

Description

@sanogueralorenzo

Summary

The generated OpenCode plugin can fire session-start twice for the same session because currentSessionID is updated only after an await.

Problem

Current generated code:

case "session.created": {
  const session = (event as any).properties?.info
  if (!session?.id) break
  // Reset per-session tracking state when switching sessions.
  if (currentSessionID !== session.id) {
    seenUserMessages.clear()
    messageStore.clear()
    currentModel = null
    await callHook("session-start", {
      session_id: session.id,
    })
  }
  currentSessionID = session.id
  break
}

Because callHook() awaits the subprocess, the handler yields before currentSessionID is updated. If another session.created event for the same session arrives during that window, it passes the same guard and fires session-start again.

Suggested fix

Update currentSessionID before the await:

case "session.created": {
  const session = (event as any).properties?.info
  if (!session?.id) break

  if (currentSessionID !== session.id) {
    seenUserMessages.clear()
    messageStore.clear()
    currentModel = null
    currentSessionID = session.id
    await callHook("session-start", {
      session_id: session.id,
    })
  }

  break
}

Why this is safer

  • closes the race window around await callHook(...)
  • keeps session-start scoped to actual session changes
  • preserves the intended state reset behavior without duplicate hook execution

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