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

  1. Populate opts.SessionID with the session's ID before calling connect/init
  2. Obtain the ID from the parent client's metadata rather than leaving it empty
  3. 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

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


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