sipeed/picoclaw · error
get conversation for %s: %w
Error message
get conversation for %s: %w
What it means
Store().GetConversationBySessionKey returned a non-nil error right after a successful Ingest for the same sample. The lookup maps sessionKey "locomo-<sampleID>" to the internal conversation ID used for scoped retrieval; if the underlying query fails (DB error, context cancelled), the wrap 'get conversation for <id>' propagates and ingestion aborts.
Source
Thrown at cmd/membench/ingest.go:71
for _, turn := range turns {
content := turn.Speaker + ": " + turn.Text
msgs = append(msgs, seahorse.Message{
Role: "user",
Content: content,
TokenCount: len(turn.Text) / 4,
})
}
// Ingest all turns for this sample
_, err := engine.Ingest(ctx, sessionKey, msgs)
if err != nil {
return nil, fmt.Errorf("ingest sample %s: %w", sample.SampleID, err)
}
// Get the conversation ID for scoped retrieval
conv, err := store.GetConversationBySessionKey(ctx, sessionKey)
if err != nil {
return nil, fmt.Errorf("get conversation for %s: %w", sample.SampleID, err)
}
if conv == nil {
return nil, fmt.Errorf("conversation not found for %s after ingest", sample.SampleID)
}
convMap[sample.SampleID] = conv.ConversationID
log.Printf("Ingested sample %s: %d turns, convID=%d", sample.SampleID, len(turns), conv.ConversationID)
}
log.Printf("Seahorse ingestion complete: %d samples, %d conversations", len(samples), len(convMap))
return &SeahorseIngestResult{
Engine: engine,
ConvMap: convMap,
}, nil
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Check whether ctx is already cancelled and widen the deadline if so
- Verify nothing else closes the engine/DB during ingestion (single owner)
- Retry the single lookup once after a short sleep — it usually succeeds since Ingest reported OK
- Move the DB to local disk to remove network-fs read flakiness
Example fix
// before
conv, err := store.GetConversationBySessionKey(ctx, sessionKey)
if err != nil {
return nil, fmt.Errorf("get conversation for %s: %w", sample.SampleID, err)
}
// after
conv, err := store.GetConversationBySessionKey(ctx, sessionKey)
if err != nil && ctx.Err() == nil {
time.Sleep(200 * time.Millisecond)
conv, err = store.GetConversationBySessionKey(ctx, sessionKey)
}
if err != nil {
return nil, fmt.Errorf("get conversation for %s: %w", sample.SampleID, err)
} Defensive patterns
Strategy: try-catch
Try / catch
conv, err := store.GetConversationBySessionKey(ctx, sessionKey)
if err != nil {
if ctx.Err() != nil {
return nil, ctx.Err()
}
time.Sleep(200 * time.Millisecond) // fresh-write visibility
conv, err = store.GetConversationBySessionKey(ctx, sessionKey)
if err != nil {
return nil, fmt.Errorf("get conversation for %s: %w", sample.SampleID, err)
}
} Prevention
- Don't close/shutdown the engine while an ingestion loop is mid-sample
- Budget ctx deadline per-sample, not just per-run, so late samples aren't cut off
- Local disk for the store avoids post-write read flakiness
- Distinguish DB errors from cancellation before retrying
When it happens
Trigger: Sqlite read error immediately after the write (I/O error, DB closed concurrently); ctx cancelled between Ingest and the lookup; store handle invalidated by engine shutdown in another goroutine.
Common situations: Timeout budget that expires mid-sample; tests closing the engine while ingestion runs; flaky network-backed sqlite (NFS) where a fresh read races the write.
Related errors
- ingest sample %s: %w
- create seahorse engine: %w
- conversation not found for %s after ingest
- create output dir: %w
- marshal result: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/e4b1f591579b4800.
Report an issue: GitHub.