google / google/adk-go

AutoCreateSession should only create on NotFound, not on all Get errors

Open
#751 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
8.8k
Forks
1k
Avg merge
3d 14h
Merged PRs (30d)
93

Description

## Summary

When `runner.Config.AutoCreateSession` is `true`, the runner calls `sessionService.Get()` and falls back to `sessionService.Create()` on **any** error — not just when the session doesn't exist. This can silently create a new session on transient database errors (timeouts, connection failures), which is unsafe for multi-turn conversational agents that depend on session history.

## Current Behavior

In [`runner.go` lines 142-161](https://github.com/google/adk-go/blob/main/runner/runner.go#L142-L161):

```go
getResp, err := r.sessionService.Get(ctx, &session.GetRequest{...})
if err != nil {
if !r.autoCreateSession {
yield(nil, err)
return
}
// Creates on ANY error, not just NotFound
createResp, err := r.sessionService.Create(ctx, &session.CreateRequest{...})
...
}
```

All `Get` errors are treated the same — the runner does not distinguish between:
- **NotFound** (session never existed → safe to create)
- **Transient errors** (database timeout, connection refused → should fail fast)

## Problem

For multi-turn conversational agents, this behavior can silently drop conversation history:

1. User has an ongoing conversation with session `abc-123`
2. Database has a brief connectivity blip
3. `sessionService.Get("abc-123")` returns a transient error
4. Runner creates a **new empty session** with ID `abc-123` instead of surfacing the error
5. User's conversation history is silently lost

This forces multi-turn agents to implement their own get-or-create pattern with explicit error type checking rather than using `AutoCreateSession`.

## Expected Behavior

When `AutoCreateSession` is `true`, the runner should only call `Create` when the `Get` error indicates the session does not exist (e.g., `codes.NotFound`). Transient errors should be propagated to the caller.

## Suggested Fix

```go
getResp, err := r.sessionService.Get(ctx, &session.GetRequest{...})
if err != nil {
if !r.autoCreateSession || !isNotFoundError(err) {
yield(nil, err)
return
}
createResp, err := r.sessionService.Create(ctx, &session.CreateRequest{...})
...
}
```

Where `isNotFoundError` checks for gRPC `codes.NotFound` and/or the string-based `"not found"` pattern used by the database session service (which wraps `gorm.ErrRecordNotFound` as `"database error while fetching session: record not found"`).

## Workaround

We currently implement manual get-or-create logic in our service layer for multi-turn agents, bypassing `AutoCreateSession` entirely.

## Environment

- `google.golang.org/adk` v1.1.0
- Go 1.24

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.