{"record":{"id":"5876361da77db5b8","repo":"dagger/dagger","slug":"load-persisted-s-snapshot-links-cache-w","errorCode":null,"errorMessage":"load persisted %s snapshot links cache: %w","messagePattern":"load persisted (.+?) snapshot links cache: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/persisted_object.go","lineNumber":148,"sourceCode":"\t}\n\tfor _, link := range links {\n\t\tif link.Role == role {\n\t\t\treturn link, nil\n\t\t}\n\t}\n\treturn dagql.PersistedSnapshotRefLink{}, fmt.Errorf(\"missing persisted %s snapshot link role %q for result %d\", label, role, resultID)\n}\n\nfunc loadPersistedSnapshotLinksByResultID(ctx context.Context, dag *dagql.Server, resultID uint64, label string) ([]dagql.PersistedSnapshotRefLink, error) {\n\tif resultID == 0 {\n\t\treturn nil, fmt.Errorf(\"load persisted %s snapshot links: zero result ID\", label)\n\t}\n\tif _, err := persistedDecodeQuery(dag); err != nil {\n\t\treturn nil, fmt.Errorf(\"load persisted %s snapshot links query: %w\", label, err)\n\t}\n\tcache, err := dagql.EngineCache(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load persisted %s snapshot links cache: %w\", label, err)\n\t}\n\tlinks, err := cache.PersistedSnapshotLinksByResultID(ctx, resultID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load persisted %s snapshot links: %w\", label, err)\n\t}\n\treturn links, nil\n}\n\nfunc loadPersistedImmutableSnapshotByResultID(ctx context.Context, dag *dagql.Server, resultID uint64, label, role string) (bkcache.ImmutableRef, error) {\n\tlink, err := loadPersistedSnapshotLinkByResultID(ctx, dag, resultID, label, role)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tquery, err := persistedDecodeQuery(dag)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tref, err := query.SnapshotManager().GetBySnapshotID(ctx, link.RefKey, bkcache.NoUpdateLastUsed)","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/persisted_object.go#L130-L166","documentation":"Wraps a failure from dagql.EngineCache(ctx), which retrieves the engine cache from the context. Without the engine cache the persisted snapshot-link table cannot be consulted during persisted-object decoding.","triggerScenarios":"DecodePersistedObject runs loadPersistedSnapshotLinksByResultID in a context that lacks the engine cache value — e.g. a context created outside the engine session or after session teardown.","commonSituations":"Calling decode helpers from tests with a bare context.Background(); executing persisted-object decoding after the Dagger session/engine has been shut down; spawning a goroutine with a stripped context.","solutions":["Use the context handed to the engine operation (e.g. the resolver ctx) rather than a fresh context.Background().","Ensure the engine session is still alive when decoding persisted objects.","If running tests, bootstrap the context with the same engine cache installation the engine performs."],"exampleFix":"// before\ndecoded, _ := DecodePersistedObject(context.Background(), dag, payload)\n// after\ndecoded, err := DecodePersistedObject(ctx, dag, payload) // ctx from the engine resolver/session","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"links, err := loadPersistedSnapshotLinksByResultID(ctx, dag, id, label)\nif err != nil && strings.Contains(err.Error(), \"snapshot links cache\") {\n    // engine cache missing from ctx: use engine-provided ctx\n}","preventionTips":["Never strip values with context.Background() in the middle of engine work.","Ensure the engine session is alive during persisted-object decoding.","Pass resolver contexts through to helper goroutines."],"tags":["cache","context","dagger"],"backgroundTag":"missing-engine-cache-in-context","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}