{"record":{"id":"c8e7ae5f0e28bcae","repo":"dagger/dagger","slug":"resolve-id-input-q-empty-session-id","errorCode":null,"errorMessage":"resolve ID input %q: empty session ID","messagePattern":"resolve ID input %q: empty session ID","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dagql/call_request_input.go","lineNumber":113,"sourceCode":"\t\t\t}\n\t\t\treturn &ResultCallRef{Call: frame}, nil\n\t\t}\n\t\tframe, err := resultCallFromRecipeIDInput(ctx, id, memo)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmemo[dig] = frame\n\t\tif frame == nil {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn &ResultCallRef{Call: frame}, nil\n\t}\n\tclientMetadata, err := engine.ClientMetadataFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolve ID input %q: current client metadata: %w\", idInputDebugString(id), err)\n\t}\n\tif clientMetadata.SessionID == \"\" {\n\t\treturn nil, fmt.Errorf(\"resolve ID input %q: empty session ID\", idInputDebugString(id))\n\t}\n\tcache, err := EngineCache(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolve ID input %q: current dagql cache: %w\", idInputDebugString(id), err)\n\t}\n\tref, err := cache.resultCallRefByResultID(ctx, clientMetadata.SessionID, id.EngineResultID())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolve ID input %q: %w\", idInputDebugString(id), err)\n\t}\n\treturn ref, nil\n}\n\nfunc resultCallFromRecipeIDInput(ctx context.Context, id *call.ID, memo recipeCallMemo) (*ResultCall, error) {\n\tif id == nil {\n\t\treturn nil, nil\n\t}\n\tif id.IsHandle() {\n\t\treturn nil, fmt.Errorf(\"handle-form IDs cannot be converted to inline recipe calls: %s\", idInputDebugString(id))","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/dagql/call_request_input.go#L95-L131","documentation":"Handle-form IDs are resolved relative to the session that produced the underlying result: the resolver looks the result up in the per-session cache using clientMetadata.SessionID. If the metadata exists but the session ID is empty, the lookup is impossible, so the resolver rejects the ID with this error.","triggerScenarios":"resultCallRefFromIDInput receives a handle-form ID while the ctx's client metadata has an empty SessionID — e.g. metadata constructed manually without a session ID, or a request path that clears/never assigns the session.","commonSituations":"Hand-built engine.ClientMetadata structs in tests or tools; proxy/interceptor layers that strip or replace request headers carrying the session ID; a client connecting without establishing a session (e.g. using a bare connection rather than a session-scoped one).","solutions":["Connect through a properly established Dagger session so the request carries a non-empty session ID.","If constructing client metadata manually, set SessionID to the request's actual session.","Check middleware/interceptors for header stripping that removes the session ID before it reaches the engine."],"exampleFix":"// before\nmd := &engine.ClientMetadata{ClientID: id}\n// after\nmd := &engine.ClientMetadata{ClientID: id, SessionID: sessionID}","handlingStrategy":"validation","validationCode":"md, err := engine.ClientMetadataFromContext(ctx)\nif err == nil && md.SessionID == \"\" {\n    return fmt.Errorf(\"session ID missing; connect via an established session\")\n}","typeGuard":null,"tryCatchPattern":"// catch and diagnose the empty-session case\nif _, err := resultCallRefFromIDInput(ctx, id, memo); err != nil {\n    if strings.Contains(err.Error(), \"empty session ID\") {\n        // reconnect with a session-scoped client\n    }\n}","preventionTips":["Use session-scoped clients rather than raw connections.","Never hand-build ClientMetadata without filling SessionID.","Audit middleware for header stripping that drops the session ID."],"tags":["go","dagql","session","client-metadata"],"backgroundTag":"empty-session-id","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"}