dagger/dagger · warning
wait for dagql cache quiescence: %w
Error message
wait for dagql cache quiescence: %w
What it means
During Cache.Close, waitForQuiescence blocks until all in-flight cache operations and lazy evaluations have settled before persisting state. If it fails (context deadline, cancellation, or an internal error), the cache's persistence may be left dirty; the error is recorded into closeErr via errors.Join with this message prefix, and logged, but Close continues.
Source
Thrown at dagql/cache.go:3798
EmitOTelWait(stackCtx, lazySpan.SpanContext(), wcprof.WaitReasonLazy, otelWaitStartNS, time.Now().UnixNano())
}
if retry {
continue
}
return waitErr
}
}
func (c *Cache) Close(ctx context.Context) error {
c.closeOnce.Do(func() {
slog.Info(
"starting dagql cache close",
"hasSQLDB", c.sqlDB != nil,
"hasPersistDB", c.pdb != nil,
)
if err := c.waitForQuiescence(ctx); err != nil {
slog.Error("dagql cache close failed waiting for quiescence; persistence will remain dirty", "err", err)
c.closeErr = errors.Join(c.closeErr, fmt.Errorf("wait for dagql cache quiescence: %w", err))
}
if err := c.releaseCleanupError(); err != nil {
slog.Error("dagql cache close found session cleanup errors; persistence will remain dirty", "err", err)
c.closeErr = errors.Join(c.closeErr, err)
}
if c.closeErr == nil {
if err := c.persistCurrentState(ctx); err != nil {
slog.Error("failed to persist dagql cache during close", "err", err)
c.closeErr = errors.Join(c.closeErr, err)
}
}
if c.closeErr != nil {
if closeErr := closeCacheDBs(c.sqlDB, c.pdb); closeErr != nil {
slog.Error("failed to close dagql persistence databases after cache close error", "err", closeErr)
c.closeErr = errors.Join(c.closeErr, closeErr)
}
c.sqlDB = nil
c.pdb = nilView on GitHub (pinned to 82ba2681db)
Solutions
- Read the logged underlying err for the real cause (deadline vs cancellation vs internal).
- Pass a context with an adequate deadline to Close, and don't cancel it before shutdown completes.
- Ensure all queries/lazy evaluations are drained or cancelled gracefully before Close.
- If persistence integrity matters, treat this close as failed and re-run the affected work (persistence may be dirty).
Example fix
// before
cache.Close(ctx) // ctx already cancelled
// after
shutdownCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := cache.Close(shutdownCtx); err != nil {
slog.Error("cache close incomplete; persistence may be dirty", "err", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if ctx.Err() != nil {
return errors.New("shutdown context already cancelled; give Close its own deadline")
} Try / catch
if err := cache.Close(ctx); err != nil {
if strings.Contains(err.Error(), "wait for dagql cache quiescence") {
slog.Error("cache close timed out; persistence may be dirty", "err", err)
}
} Prevention
- Give Close a dedicated context with a generous timeout, independent of request contexts.
- Cancel or await all in-flight queries before shutdown.
- Watch for leaked operations that prevent quiescence in long-lived engines.
When it happens
Trigger: Close called with an already-cancelled or deadline-exceeded context while evaluations are pending; a stuck in-flight evaluation preventing quiescence; shutdown timeouts in the engine.
Common situations: Engine shutdown racing long-running queries; CI timeouts cancelling contexts before Close; leaked operations that never finish, making quiescence impossible.
Related errors
- failed parsing [%s], expected address format: [%s]
- use target SDK language: %s: %w
- unmarshal introspection json: %w
- failed to apply generated code: %w
- failed to connect to engine: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/0e120225b2f12634.
Report an issue: GitHub.