sipeed/picoclaw · error
create seahorse engine: %w
Error message
create seahorse engine: %w
What it means
seahorse.NewEngine failed while building the memory engine for the membench harness. NewEngine opens/creates the sqlite database at dbPath and initializes its schema, so this wrap carries whatever the storage layer reported: unusable path, locked/corrupt DB, schema-version mismatch, or permission problems. Without the engine, LOCOMO ingestion cannot start.
Source
Thrown at cmd/membench/ingest.go:31
// SeahorseIngestResult holds the results of ingesting into seahorse.
type SeahorseIngestResult struct {
Engine *seahorse.Engine
ConvMap ConvMap // sampleID → conversationID
}
// IngestSeahorse loads all LOCOMO samples into a seahorse Engine.
// Returns the engine and a mapping from sampleID to conversationID for scoped retrieval.
func IngestSeahorse(ctx context.Context, samples []LocomoSample, dbPath string) (*SeahorseIngestResult, error) {
noopFn := func(ctx context.Context, prompt string, opts seahorse.CompleteOptions) (string, error) {
return "", nil
}
engine, err := seahorse.NewEngine(seahorse.Config{
DBPath: dbPath,
}, noopFn)
if err != nil {
return nil, fmt.Errorf("create seahorse engine: %w", err)
}
store := engine.GetRetrieval().Store()
convMap := make(ConvMap)
for si := range samples {
sample := &samples[si]
sessionKey := "locomo-" + sample.SampleID
// Check if conversation already exists (idempotent)
existing, _ := store.GetConversationBySessionKey(ctx, sessionKey)
if existing != nil {
convMap[sample.SampleID] = existing.ConversationID
log.Printf("Skipping existing sample %s: convID=%d", sample.SampleID, existing.ConversationID)
continue
}
turns := GetTurns(sample)View on GitHub (pinned to 49183d7e8d)
Solutions
- Ensure the parent directory of dbPath exists and is writable (mkdir -p)
- Kill the other process holding the DB, or wait for it to exit before rerunning
- If the DB is stale/corrupt from an older version, move it aside (mv bench.db bench.db.bak) and let ingestion rebuild
- Run the engine on a local filesystem, not NFS/sshfs, to avoid sqlite locking issues
Example fix
// before
engine, err := seahorse.NewEngine(seahorse.Config{DBPath: dbPath}, noopFn)
// after
if dir := filepath.Dir(dbPath); dir != "" {
if err := os.MkdirAll(dir, 0o755); err != nil {
return nil, fmt.Errorf("prepare db dir: %w", err)
}
}
engine, err := seahorse.NewEngine(seahorse.Config{DBPath: dbPath}, noopFn) Defensive patterns
Strategy: try-catch
Validate before calling
if dir := filepath.Dir(dbPath); dir != "" && dir != "." {
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("db parent dir: %w", err)
}
}
if f, err := os.OpenFile(dbPath, os.O_RDWR|os.O_CREATE, 0o644); err != nil {
return fmt.Errorf("db path not writable: %w", err)
} else {
f.Close()
} Try / catch
engine, err := seahorse.NewEngine(seahorse.Config{DBPath: dbPath}, noopFn)
if err != nil {
if strings.Contains(err.Error(), "locked") || strings.Contains(err.Error(), "busy") {
return nil, fmt.Errorf("db %s in use by another run: %w", dbPath, err)
}
return nil, fmt.Errorf("create seahorse engine: %w", err)
} Prevention
- One process per dbPath; serialize membench runs
- Pre-create and probe-writable the db directory before the run
- Keep the DB on local disk; sqlite locks misbehave on NFS
- Archive (don't reuse) DB files across engine version upgrades
When it happens
Trigger: dbPath's parent directory missing or unwritable; another membench/process holding the sqlite file (SQLITE_BUSY / database is locked); dbPath points at a non-DB file; old schema from a previous membench version; read-only filesystem.
Common situations: Rerunning membench while a previous run is still alive; pointing -db at a path on a read-only container volume; mixing engine versions against a stale DB file; path with a typo creating an unusable location.
Related errors
- ingest sample %s: %w
- get conversation for %s: %w
- create output dir: %w
- marshal result: %w
- write result: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/8ed95615bbc97648.
Report an issue: GitHub.