dagger/dagger · error
decode persisted container payload: %w
Error message
decode persisted container payload: %w
What it means
Decoding a persisted container failed at the first step: the stored JSON payload could not be unmarshaled into persistedContainerPayload. The cached container entry is corrupt or was written with a different schema than this version expects. The underlying unmarshal error is wrapped for diagnosis.
Source
Thrown at core/container.go:1643
Owner: socket.Owner,
})
}
enc, err := json.Marshal(payload)
if err != nil {
return dagql.PersistedObjectEncoding{}, fmt.Errorf("marshal persisted container payload: %w", err)
}
return dagql.PersistedObjectEncoding{
JSON: enc,
SnapshotLinks: snapshotLinks,
}, nil
}
//nolint:gocyclo // flat persisted-container dispatch over mount, secret, and socket kinds.
func (*Container) DecodePersistedObject(ctx context.Context, dag *dagql.Server, resultID uint64, call *dagql.ResultCall, payload json.RawMessage) (dagql.Typed, error) {
var persisted persistedContainerPayload
if err := json.Unmarshal(payload, &persisted); err != nil {
return nil, fmt.Errorf("decode persisted container payload: %w", err)
}
if persisted.Form == "" {
persisted.Form = persistedContainerFormReady
}
fs := new(LazyAccessor[*Directory, *Container])
var decodedRootFS decodedContainerDirectoryValue
if len(persisted.FS) > 0 {
rootfs, err := decodePersistedContainerDirectoryValue(ctx, dag, resultID, "fs", persisted.FS)
if err != nil {
return nil, err
}
decodedRootFS = rootfs
if rootfs.Dir != nil {
fs.setValue(rootfs.Dir)
}
}
View on GitHub (pinned to 82ba2681db)
Solutions
- Prune the Dagger engine cache and re-run the pipeline
- Align the engine version with the one that wrote the cache entries
- Inspect the wrapped error for the specific JSON field mismatch
- Re-encode the container result instead of reusing the cached entry
Example fix
// before: reusing stale persisted entry
ctr, err := container.DecodePersistedObject(ctx, dag, resultID, call, payload)
// after: on decode failure, recompute the container
ctr, err := container.DecodePersistedObject(ctx, dag, resultID, call, payload)
if err != nil {
return recomputeContainer(ctx, dag)
} Defensive patterns
Strategy: try-catch
Validate before calling
var probe persistedContainerProbe
if err := json.Unmarshal(payload, &probe); err != nil || probe.Form == "" && len(payload) == 0 {
// treat cache entry as corrupt; skip or prune
} Try / catch
typed, err := container.DecodePersistedObject(ctx, dag, resultID, call, payload)
if err != nil {
// corrupt/incompatible entry: recompute the container instead of failing
return recomputeContainer(ctx, dag)
} Prevention
- Prune the engine cache after version upgrades/downgrades
- Unify Dagger versions across runners sharing a cache backend
- Preserve the wrapped error for diagnosing the exact JSON mismatch
When it happens
Trigger: DecodePersistedObject receives a payload whose JSON structure doesn't match persistedContainerPayload — wrong field types, truncated JSON, or entries written by an incompatible Dagger version.
Common situations: Engine upgrade/downgrade across persisted-object schema changes; shared cache backends with mixed engine versions; corrupted cache storage.
Related errors
- decode persisted container file value: %w
- decode persisted service payload: %w
- marshal pending container directory value: %w
- marshal pending container file value: %w
- decode persisted container directory value: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/e72796e23062b406.
Report an issue: GitHub.