dagger/dagger · error
wipe unclean persistence db: %w
Error message
wipe unclean persistence db: %w
What it means
After detecting an unclean shutdown, NewCache wipes the SQLite persistence files via wipeSQLiteFiles(dbPath) so the engine can cold-start with a fresh cache. If that deletion fails (permissions, file locks, read-only mount), this wrapped error aborts cache initialization.
Source
Thrown at dagql/cache.go:458
c.pdb = persistDB
}
cleanShutdownVal, found, err := c.pdb.SelectMetaValue(ctx, persistdb.MetaKeyCleanShutdown)
if err != nil {
if closeErr := closeCacheDBs(db, c.pdb); closeErr != nil {
return nil, errors.Join(fmt.Errorf("read clean_shutdown metadata: %w", err), closeErr)
}
return nil, fmt.Errorf("read clean_shutdown metadata: %w", err)
}
if found && cleanShutdownVal != "1" {
c.persistenceResetReason = CachePersistenceResetUncleanShutdown
c.tracePersistStoreWipedUncleanShutdown(ctx, cleanShutdownVal)
slog.Warn("dagql persistence store marked unclean; wiping and cold-starting", "cleanShutdown", cleanShutdownVal)
if closeErr := closeCacheDBs(db, c.pdb); closeErr != nil {
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)View on GitHub (pinned to 82ba2681db)
Solutions
- Verify the cache volume is writable and has space (mount options, df).
- Ensure no other process holds the DB files open, then retry startup.
- Fix file ownership/permissions (chown/chmod) or remove immutable flags (chattr -i).
- Manually delete dbPath cache files while stopped and start the engine again.
Example fix
// before: crash leaves unclean DB on read-only volume wipe unclean persistence db: permission denied // after $ sudo mount -o remount,rw /var/lib/dagger && rm -f /var/lib/dagger/cache.db*
Defensive patterns
Strategy: validation
Validate before calling
// before engine start, ensure the wipe is possible: writable dir, no leftover locks
func wipeable(dbPath string) error {
if err := unix.Access(dbPath, unix.W_OK); err != nil { return err }
for _, f := range []string{dbPath + "-wal", dbPath + "-shm"} {
if err := os.Remove(f); err != nil && !os.IsNotExist(err) { return err }
}
return nil
} Prevention
- Mount the cache volume read-write with adequate free space
- Chown the cache dir to the engine's runtime user
- Prevent concurrent engines on shared cache volumes
- Use local SSD/local storage rather than network mounts
When it happens
Trigger: NewCache finds cleanShutdownVal != "1", successfully closes both DBs, then wipeSQLiteFiles(dbPath) fails to unlink the db/-wal/-shm files.
Common situations: Cache directory on a read-only or full volume after a crash; another process holding the deleted files open; immutable attribute or wrong ownership on cache files; container with a mounted cache dir lacking write access.
Related errors
- wipe persistence db after import failure: %w
- wipe schema-mismatched persistence db: %w
- read schema_version metadata: %w
- close db before schema-version wipe
- read clean_shutdown metadata: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/cd156e324b508cc7.
Report an issue: GitHub.