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 initializing

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Ensure the caller sets engine.ClientMetadata with a valid SessionID before making calls
  2. Check where the metadata was produced for why SessionID is empty
  3. Re-create the session via the SDK so a real session ID is issued
  4. 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

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


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