dagger/dagger · error
session ID is required
Error message
session ID is required
What it means
Returned by Server.getOrInitClient when ClientInitOpts.SessionID is empty. Every engine session is keyed by session ID; the transport or caller omitted it, which is a protocol violation caught before any client state is created.
Source
Thrown at engine/server/session.go:1162
return client, nil
}
// initialize session+client if needed, return:
// * the initialized client
// * a cleanup func to run when the call is done
//
//nolint:gocyclo // session/client initialization is an intentionally linear state machine.
func (srv *Server) getOrInitClient(
ctx context.Context,
opts *ClientInitOpts,
) (_ *daggerClient, _ func() error, rerr error) {
if srv.isShuttingDown() {
return nil, nil, errServerShuttingDown
}
sessionID := opts.SessionID
if sessionID == "" {
return nil, nil, fmt.Errorf("session ID is required")
}
clientID := opts.ClientID
if clientID == "" {
return nil, nil, fmt.Errorf("client ID is required")
}
token := opts.ClientSecretToken
if token == "" {
return nil, nil, fmt.Errorf("client secret token is required")
}
// cleanup to do if this method fails; the failure handler that runs these is
// installed below, once we hold the session's lifecycleMu (so it can publish
// the removed tombstone before unlocking, then drop it only after cleanups).
failureCleanups := &cleanups.Cleanups{}
// get or initialize the session as a whole
srv.daggerSessionsMu.Lock()View on GitHub (pinned to 82ba2681db)
Solutions
- Populate opts.SessionID with the session's ID before calling connect/init
- Obtain the ID from the parent client's metadata rather than leaving it empty
- Fix the SDK/tool path that builds ClientInitOpts to always propagate the session ID
Example fix
// before
opts := &ClientInitOpts{ClientID: cid, ClientSecretToken: tok}
// after
opts := &ClientInitOpts{SessionID: sessID, ClientID: cid, ClientSecretToken: tok} Defensive patterns
Strategy: validation
Validate before calling
if opts.SessionID == "" { return errors.New("SessionID must be set before connecting") } Type guard
func optsValid(o *ClientInitOpts) bool { return o != nil && o.SessionID != "" && o.ClientID != "" && o.ClientSecretToken != "" } Try / catch
if err := connect(opts); err != nil {
if strings.Contains(err.Error(), "session ID is required") { return fmt.Errorf("caller bug: SessionID not set: %w", err) }
return err
} Prevention
- Validate ClientInitOpts fields before passing them to connect APIs
- Source SessionID from the parent client's metadata
- Add a unit test asserting opts are fully populated
When it happens
Trigger: ClientInitOpts constructed programmatically (e.g. by an SDK or nested-client path) without setting SessionID.
Common situations: Custom tooling or module code building client init options by hand; SDK bug leaving metadata unset; constructing options from a zero-valued struct.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- unknown sdk config keys found %v
- key %q cannot be stored in user-level config; only modules.<
- bind session resource: empty session ID
- bind session resource: empty client ID
- metadata prune: maximum estimated bytes must be positive
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/5315bc695f50380b.
Report an issue: GitHub.