dagger/dagger · error
close db before import-wipe
Error message
close db before import-wipe
What it means
When importing persisted state back into the freshly opened cache fails, NewCache attempts a wipe-and-cold-start recovery. Before wiping it must close both DBs; if closeCacheDBs fails, this "close db before import-wipe" error is returned (joined with the close error), aborting startup instead of performing the recovery wipe.
Source
Thrown at dagql/cache.go:473
return nil, errors.Join(fmt.Errorf("close db before wipe"), closeErr)
}
if err := wipeSQLiteFiles(dbPath); err != nil {
return nil, fmt.Errorf("wipe unclean persistence db: %w", err)
}
db, persistDB, err = prepareCacheDBs(ctx, dbPath)
if err != nil {
return nil, err
}
c.sqlDB = db
c.pdb = persistDB
}
if err := c.importPersistedState(ctx); err != nil {
c.persistenceResetReason = CachePersistenceResetImportFailure
c.tracePersistStoreWipedImportFailure(ctx, err)
slog.Warn("dagql persistence import failed; wiping and cold-starting", "err", err)
if closeErr := closeCacheDBs(db, c.pdb); closeErr != nil {
return nil, errors.Join(fmt.Errorf("close db before import-wipe"), closeErr)
}
if err := wipeSQLiteFiles(dbPath); err != nil {
return nil, fmt.Errorf("wipe persistence db after import failure: %w", err)
}
db, persistDB, err = prepareCacheDBs(ctx, dbPath)
if err != nil {
return nil, err
}
c.sqlDB = db
c.pdb = persistDB
}
if err := c.pdb.UpsertMeta(ctx, persistdb.MetaKeySchemaVersion, cachePersistenceSchemaVersion); err != nil {
if closeErr := closeCacheDBs(db, c.pdb); closeErr != nil {
return nil, errors.Join(fmt.Errorf("set persistence schema version: %w", err), closeErr)
}
return nil, fmt.Errorf("set persistence schema version: %w", err)
}View on GitHub (pinned to 82ba2681db)
Solutions
- Stop any other dagger/engine process sharing the cache path, then restart so the close+wipe can succeed.
- Check free disk space and filesystem health before restarting.
- Delete the persistence files manually while the engine is stopped and let the next start cold-initialize.
- Ensure the same Dagger version is used for the cache dir (avoid version mixing on shared volumes).
Example fix
// before: import fails, close also fails (second instance holds lock) $ dagger run ... # aborts // after $ kill <other-engine-pid>; rm -f /var/lib/dagger/cache.db*; restart dagger
Defensive patterns
Strategy: try-catch
Validate before calling
// only one instance, writable dir, sane timeout before an import-heavy init
func preflight(dbPath string) error {
if err := unix.Access(dbPath, unix.W_OK); err != nil { return err }
return os.MkdirAll(filepath.Dir(dbPath+".lock"), 0o755) // + lockfile discipline
} Try / catch
c, err := dagql.NewCache(ctx, dbPath, sm, gc)
if err != nil && strings.Contains(err.Error(), "close db before import-wipe") {
// another holder blocked the recovery close: clear and retry once
os.Remove(dbPath); os.Remove(dbPath+"-wal"); os.Remove(dbPath+"-shm")
c, err = dagql.NewCache(ctx, dbPath, sm, gc)
}
if err != nil { return err } Prevention
- Never run two engines against one cache dir
- Give startup a generous context timeout for large persisted state
- Keep the cache on reliable local storage
- Upgrade the whole fleet to the same Dagger version before sharing volumes
When it happens
Trigger: c.importPersistedState(ctx) returns an error (corrupt/incompatible persisted data, parse failure, context cancelled), then closeCacheDBs(db, c.pdb) also returns an error during the recovery path.
Common situations: Persistence snapshot written by an older/newer Dagger version with incompatible format; truncated cache file after crash; recovery running on a disk that is full or has a locked DB (another instance attached); context deadline exceeded during long import.
Related errors
- close db before wipe
- read schema_version metadata: %w
- close db before schema-version wipe
- wipe schema-mismatched persistence db: %w
- read clean_shutdown metadata: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/9b88bf82af489f68.
Report an issue: GitHub.