temporalio/temporal · error

no nexus context set on context

Error message

no nexus context set on context

What it means

Raised by getOperationContext when the request context does not carry a nexusContext value, meaning the Nexus operation handler was invoked outside the framework that injects Nexus request metadata (namespace, endpoint, header info). StartOperation/CancelOperation depend on this context to resolve the namespace and set up metrics/logging.

Source

Thrown at service/frontend/nexus_handler.go:371

	auth                          *authorization.Interceptor
	telemetryInterceptor          *interceptor.TelemetryInterceptor
	requestErrorHandler           *interceptor.RequestErrorHandler
	redirectionInterceptor        *interceptor.Redirection
	forwardingEnabledForNamespace dynamicconfig.BoolPropertyFnWithNamespaceFilter
	forwardingClients             *cluster.FrontendHTTPClientCache
	payloadSizeLimit              dynamicconfig.IntPropertyFnWithNamespaceFilter
	headersBlacklist              dynamicconfig.TypedPropertyFn[*regexp.Regexp]
	useForwardByEndpoint          dynamicconfig.BoolPropertyFn
	metricTagConfig               dynamicconfig.TypedPropertyFn[chasmnexus.NexusMetricTagConfig]
	httpTraceProvider             commonnexus.HTTPClientTraceProvider
}

// Extracts a nexusContext from the given ctx and returns an operationContext with tagged metrics and logging.
// Resolves the context's namespace name to a registered Namespace.
func (h *nexusHandler) getOperationContext(ctx context.Context, method string) (*operationContext, error) {
	nc, ok := ctx.Value(nexusContextKey{}).(*nexusContext)
	if !ok {
		return nil, errors.New("no nexus context set on context")
	}
	oc := operationContext{
		nexusContext:                  nc,
		method:                        method,
		clusterMetadata:               h.clusterMetadata,
		clientVersionChecker:          headers.NewDefaultVersionChecker(),
		auth:                          h.auth,
		telemetryInterceptor:          h.telemetryInterceptor,
		requestErrorHandler:           h.requestErrorHandler,
		redirectionInterceptor:        h.redirectionInterceptor,
		forwardingEnabledForNamespace: h.forwardingEnabledForNamespace,
		headersBlacklist:              h.headersBlacklist,
		metricTagConfig:               h.metricTagConfig,
		cleanupFunctions:              make([]func(map[string]string, error), 0),
	}
	oc.metricsHandlerForInterceptors = h.metricsHandler.WithTags(
		metrics.OperationTag(method),
		metrics.NamespaceTag(nc.namespaceName),

View on GitHub (pinned to bde624efd1)

Solutions

  1. Invoke the Nexus handler through the nexus framework request path so the framework-injected context is passed through
  2. In tests, build the context with the nexusContextKey value (or use the handler's provided test helpers) before calling StartOperation/CancelOperation
  3. Audit any middleware/wrapping code to ensure it propagates ctx unchanged rather than replacing it

Example fix

// before
ctx := context.Background()
h.StartOperation(ctx, req)
// after
ctx = context.WithValue(ctx, nexusContextKey{}, nc)
h.StartOperation(ctx, req)
Defensive patterns

Strategy: type-guard

Type guard

func nexusContextFromCtx(ctx context.Context) (*nexusContext, bool) {
  nc, ok := ctx.Value(nexusContextKey{}).(*nexusContext)
  return nc, ok
}

Prevention

When it happens

Trigger: Calling StartOperation or CancelOperation (or code paths that call getOperationContext) with a plain context.Context instead of the request context delivered by the Nexus framework through the handler.

Common situations: Tests invoking handler methods directly with context.Background(), custom handler wrappers that strip the context, or calling handler internals from unrelated RPC paths.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/9063f36b7a80410e. Report an issue: GitHub.