dagger/dagger · error
missing session ID
Error message
missing session ID
What it means
clientFromIDs validates that a non-empty session ID was supplied before looking up the session in srv.daggerSessions. An empty session ID means the call cannot be routed to any session, so this sentinel error is returned.
Source
Thrown at engine/server/session.go:1097
return client.getClientCaller(ctx, id)
}
func (srv *Server) clientFromContext(ctx context.Context) (*daggerClient, error) {
clientMetadata, err := engine.ClientMetadataFromContext(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get client metadata for session call: %w", err)
}
client, err := srv.clientFromIDs(clientMetadata.SessionID, clientMetadata.ClientID)
if err != nil {
return nil, err
}
return client, nil
}
func (srv *Server) clientFromIDs(sessID, clientID string) (*daggerClient, error) {
if sessID == "" {
return nil, fmt.Errorf("missing session ID")
}
if clientID == "" {
return nil, fmt.Errorf("missing client ID")
}
srv.daggerSessionsMu.RLock()
sess, ok := srv.daggerSessions[sessID]
srv.daggerSessionsMu.RUnlock()
if !ok {
// This error can happen due to per-LLB-vertex deduplication in the buildkit solver,
// where for instance the first client cancels and closes its session while others
// are waiting on the result. In this case its safe to retry the operation again with
// the still connected client metadata.
err := flightcontrol.RetryableError{Err: fmt.Errorf("session %q not found", sessID)}
return nil, err
}
// Gate on the session's lifecycle state via a lock-free atomic read (never
// lifecycleMu), so this lookup can't block on a session that is initializingView on GitHub (pinned to 82ba2681db)
Solutions
- Ensure the caller sets engine.ClientMetadata with a valid SessionID before making calls
- Check where the metadata was produced for why SessionID is empty
- Re-create the session via the SDK so a real session ID is issued
- Verify SDK/engine version compatibility for metadata encoding
Example fix
// before
client, err := srv.clientFromIDs(md.SessionID, md.ClientID) // md.SessionID == ""
// after
custom := engine.ClientMetadata{SessionID: sessID, ClientID: md.ClientID}
client, err := srv.clientFromIDs(custom.SessionID, custom.ClientID) Defensive patterns
Strategy: validation
Validate before calling
// Go
if md.SessionID == "" {
return errors.New("cannot call engine: session ID is empty")
} Try / catch
// Go
if err != nil && err.Error() == "missing session ID" {
// re-create the session and retry the call
} Prevention
- Never construct zero-value ClientMetadata structs
- Obtain session IDs from Connect/session setup
- Validate metadata before internal calls
When it happens
Trigger: A call path resolves client metadata whose SessionID field is the empty string, then calls srv.clientFromIDs("", clientID).
Common situations: Malformed or absent client metadata on the wire, custom tooling invoking engine internals without a session, or bugs where a default/zero-value ClientMetadata struct is passed through.
Related errors
- missing client ID
- failed to get engine client: %w
- buildkit: %w
- failed to get engine client: %w
- module source engine client: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/11a7af10aa74a370.
Report an issue: GitHub.