dagger/dagger · error
failed to get session ID from client metadata
Error message
failed to get session ID from client metadata
What it means
After retrieving client metadata, the secret resolver requires a non-empty SessionID; otherwise it throws "failed to get session ID from client metadata". Session ID scoping keeps secret cache keys isolated per client session, so an empty one is rejected.
Source
Thrown at core/schema/secret.go:80
URI string
CacheKey dagql.Optional[dagql.String]
}
func (s *secretSchema) secret(
ctx context.Context,
parent dagql.ObjectResult[*core.Query],
args secretArgs,
) (dagql.ObjectResult[*core.Secret], error) {
srv, err := core.CurrentDagqlServer(ctx)
if err != nil {
return dagql.ObjectResult[*core.Secret]{}, fmt.Errorf("failed to get dagql server: %w", err)
}
clientMetadata, err := engine.ClientMetadataFromContext(ctx)
if err != nil {
return dagql.ObjectResult[*core.Secret]{}, fmt.Errorf("failed to get client metadata from context: %w", err)
}
if clientMetadata.SessionID == "" {
return dagql.ObjectResult[*core.Secret]{}, fmt.Errorf("failed to get session ID from client metadata")
}
cache, err := dagql.EngineCache(ctx)
if err != nil {
return dagql.ObjectResult[*core.Secret]{}, fmt.Errorf("failed to get dagql cache: %w", err)
}
if _, _, err := secretprovider.ResolverForID(args.URI); err != nil {
return dagql.ObjectResult[*core.Secret]{}, err
}
concreteVal := &core.Secret{
URIVal: args.URI,
SourceClientID: clientMetadata.ClientID,
}
var handle dagql.SessionResourceHandle
if args.CacheKey.Valid {
handle = core.SecretHandleFromCacheKey(string(args.CacheKey.Value))
} else {
plaintext, err := concreteVal.Plaintext(ctx)View on GitHub (pinned to 82ba2681db)
Solutions
- Ensure the client sends its session ID with each request (the SDKs do this automatically)
- When constructing ClientMetadata manually, always set SessionID to a non-empty unique value
- Regenerate a fresh session (new dagger session) if the ID was lost
Example fix
// before
md := &engine.ClientMetadata{ClientID: clientID}
// after
md := &engine.ClientMetadata{ClientID: clientID, SessionID: sessionID} Defensive patterns
Strategy: validation
Validate before calling
md, err := engine.ClientMetadataFromContext(ctx)
if err != nil { return err }
if md.SessionID == "" { return errors.New("SessionID must be set") } Type guard
func hasSessionID(md *engine.ClientMetadata) bool {
return md != nil && md.SessionID != ""
} Prevention
- Always set SessionID when constructing ClientMetadata manually
- Rely on SDKs which generate a session ID per session automatically
- Treat empty session IDs as a bug in embedded engine setup
When it happens
Trigger: A request reaches the secret query with ClientMetadata present but SessionID == "" — e.g. metadata constructed without a session ID, or a client that omits the session header.
Common situations: Custom/engine-embedded clients building ClientMetadata manually without SessionID; stale session bookkeeping in embedded engine setups.
Related errors
- directory no-op equivalence: empty session ID
- local LLM: parent client metadata: %w
- empty session ID
- failed to get main client caller ID: %w
- resolve volatile variable %q: current client metadata: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/4b6d01f88b8b76bc.
Report an issue: GitHub.