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

  1. Ensure the client sends its session ID with each request (the SDKs do this automatically)
  2. When constructing ClientMetadata manually, always set SessionID to a non-empty unique value
  3. 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

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


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/4b6d01f88b8b76bc. Report an issue: GitHub.