dagger/dagger · error
load %dth value from %T: reconstruct result: %w
Error message
load %dth value from %T: reconstruct result: %w
What it means
Result[T].NthValue (dagql/cache.go:2945) fails at the last rehydration step: wrapSharedResultWithResolver is called to rebuild a live result (rebinding the resolver) from the stored shared result. Any failure inside that reconstruction — decoding the stored result, missing type/resolver registration, or an internal dagql error — is surfaced wrapped as 'reconstruct result'.
Source
Thrown at dagql/cache.go:2945
srv := CurrentDagqlServer(ctx)
if srv == nil {
return nil, fmt.Errorf("load %dth value from %T: missing dagql server in context", nth, self)
}
clientMetadata, err := engine.ClientMetadataFromContext(ctx)
if err != nil {
return nil, fmt.Errorf("load %dth value from %T: current client metadata: %w", nth, self, err)
}
if clientMetadata.SessionID == "" {
return nil, fmt.Errorf("load %dth value from %T: empty session ID", nth, self)
}
cache, err := EngineCache(ctx)
if err != nil {
return nil, fmt.Errorf("load %dth value from %T: current dagql cache: %w", nth, self, err)
}
touchSharedResultLastUsed(childShared, time.Now().UnixNano())
retResAny, err := wrapSharedResultWithResolver(ctx, childShared, true, srv)
if err != nil {
return nil, fmt.Errorf("load %dth value from %T: reconstruct result: %w", nth, self, err)
}
if err := cache.trackSessionResult(ctx, clientMetadata.SessionID, retResAny, true); err != nil {
return nil, fmt.Errorf("load %dth value from %T: claim cache-backed result: %w", nth, self, err)
}
return retResAny, nil
}
srv := CurrentDagqlServer(ctx)
if srv == nil {
return nil, fmt.Errorf("load %dth value from %T: missing dagql server in context", nth, self)
}
if parentCall.Type == nil || parentCall.Type.Elem == nil {
return nil, fmt.Errorf("cannot get %dth value from %T without element type", nth, self)
}
req := &CallRequest{
ResultCall: parentCall.fork(),
}
req.Type = req.Type.Elem.clone()View on GitHub (pinned to 82ba2681db)
Solutions
- Retry the operation with a fresh session — if the entry was reaped mid-load, the new call recreates the result normally.
- Restart/clear the engine cache if entries are persistently corrupt (delete the engine cache data directory), then rerun.
- Ensure all DAG types/resolvers are registered on the server before any results can be reconstructed (complete object registration at server setup).
- Align engine versions between components so cached entries match the current schema/type registrations; check dagql server setup for missing Register calls.
Example fix
// before
// types registered lazily/late; cached results may resolve before Register happens
server := dagql.New(ctx, dagql.CacheConfig{})
// after
server := dagql.New(ctx, dagql.CacheConfig{})
core.RegisterTypes(ctx, server) // register everything up-front Defensive patterns
Strategy: retry
Validate before calling
// ensure types are registered before resolving cached results
func serverReady(ctx context.Context, srv *dagql.Server) error {
// registration happens at startup; here just verify ctx inputs
if _, err := engine.ClientMetadataFromContext(ctx); err != nil {
return err
}
if _, err := EngineCache(ctx); err != nil {
return err
}
return nil
} Type guard
func isReconstructionError(err error) bool {
return err != nil && strings.Contains(err.Error(), "reconstruct result")
} Try / catch
val, err := listResult.NthValue(ctx, nth)
if err != nil {
if isReconstructionError(err) {
// likely a reaped/racing entry: retry with a fresh call/session
return retryNthValueWithFreshSession(ctx, listResult, nth)
}
return nil, err
} Prevention
- Retry once with a fresh session on reconstruction errors — transient reaping races self-heal.
- Register all DAG types/resolvers at server startup, never lazily after results exist.
- Keep engine versions consistent across components so cached entries match current schemas.
- If errors persist, clear the engine cache data directory to purge corrupt entries.
When it happens
Trigger: wrapSharedResultWithResolver errors while re-wrapping a cache-backed shared result during NthValue: corrupt/evicted cache entry read mid-decode, result type whose resolver registration is missing on this build, or an internal error in the server's wrap path.
Common situations: Cache entries touched concurrently with GC/reaping (session released mid-load); engine binary mix where old cached entries reference types not registered after an upgrade/downgrade; genuinely corrupt engine cache state on disk.
Related errors
- wait: normalize returned result: %w
- load %s: %w
- failed parsing [%s], expected address format: [%s]
- use target SDK language: %s: %w
- unmarshal introspection json: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/640a4ac88182efb2.
Report an issue: GitHub.