{"record":{"id":"8ed95615bbc97648","repo":"sipeed/picoclaw","slug":"create-seahorse-engine-w","errorCode":null,"errorMessage":"create seahorse engine: %w","messagePattern":"create seahorse engine: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/membench/ingest.go","lineNumber":31,"sourceCode":"\n// SeahorseIngestResult holds the results of ingesting into seahorse.\ntype SeahorseIngestResult struct {\n\tEngine  *seahorse.Engine\n\tConvMap ConvMap // sampleID → conversationID\n}\n\n// IngestSeahorse loads all LOCOMO samples into a seahorse Engine.\n// Returns the engine and a mapping from sampleID to conversationID for scoped retrieval.\nfunc IngestSeahorse(ctx context.Context, samples []LocomoSample, dbPath string) (*SeahorseIngestResult, error) {\n\tnoopFn := func(ctx context.Context, prompt string, opts seahorse.CompleteOptions) (string, error) {\n\t\treturn \"\", nil\n\t}\n\n\tengine, err := seahorse.NewEngine(seahorse.Config{\n\t\tDBPath: dbPath,\n\t}, noopFn)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create seahorse engine: %w\", err)\n\t}\n\n\tstore := engine.GetRetrieval().Store()\n\tconvMap := make(ConvMap)\n\n\tfor si := range samples {\n\t\tsample := &samples[si]\n\t\tsessionKey := \"locomo-\" + sample.SampleID\n\n\t\t// Check if conversation already exists (idempotent)\n\t\texisting, _ := store.GetConversationBySessionKey(ctx, sessionKey)\n\t\tif existing != nil {\n\t\t\tconvMap[sample.SampleID] = existing.ConversationID\n\t\t\tlog.Printf(\"Skipping existing sample %s: convID=%d\", sample.SampleID, existing.ConversationID)\n\t\t\tcontinue\n\t\t}\n\n\t\tturns := GetTurns(sample)","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/membench/ingest.go#L13-L49","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nengine, err := seahorse.NewEngine(seahorse.Config{DBPath: dbPath}, noopFn)\n\n// after\nif dir := filepath.Dir(dbPath); dir != \"\" {\n    if err := os.MkdirAll(dir, 0o755); err != nil {\n        return nil, fmt.Errorf(\"prepare db dir: %w\", err)\n    }\n}\nengine, err := seahorse.NewEngine(seahorse.Config{DBPath: dbPath}, noopFn)","handlingStrategy":"try-catch","validationCode":"if dir := filepath.Dir(dbPath); dir != \"\" && dir != \".\" {\n    if err := os.MkdirAll(dir, 0o755); err != nil {\n        return fmt.Errorf(\"db parent dir: %w\", err)\n    }\n}\nif f, err := os.OpenFile(dbPath, os.O_RDWR|os.O_CREATE, 0o644); err != nil {\n    return fmt.Errorf(\"db path not writable: %w\", err)\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"engine, err := seahorse.NewEngine(seahorse.Config{DBPath: dbPath}, noopFn)\nif err != nil {\n    if strings.Contains(err.Error(), \"locked\") || strings.Contains(err.Error(), \"busy\") {\n        return nil, fmt.Errorf(\"db %s in use by another run: %w\", dbPath, err)\n    }\n    return nil, fmt.Errorf(\"create seahorse engine: %w\", err)\n}","preventionTips":["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"],"tags":["go","database","sqlite","memory-engine","benchmark"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}