wavetermdev/waveterm · error

missing UIContext for %s.%s

Error message

missing UIContext for %s.%s

What it means

Some Wave Terminal service methods take a wavebase.UIContext parameter that carries the calling block/window context. CallService iterates the method's parameters via reflection and, when it finds a UIContext parameter, requires webCall.UIContext to be non-nil. This error means the method requires a UIContext but the RPC request did not include one.

Source

Thrown at pkg/service/service.go:336

	svcObj := ServiceMap[webCall.Service]
	if svcObj == nil {
		return webErrorRtn(fmt.Errorf("invalid service: %q", webCall.Service))
	}
	method := reflect.ValueOf(svcObj).MethodByName(webCall.Method)
	if !method.IsValid() {
		return webErrorRtn(fmt.Errorf("invalid method: %s.%s", webCall.Service, webCall.Method))
	}
	var valueArgs []reflect.Value
	argIdx := 0
	for idx := 0; idx < method.Type().NumIn(); idx++ {
		argType := method.Type().In(idx)
		if idx == 0 && argType == contextRType {
			valueArgs = append(valueArgs, reflect.ValueOf(ctx))
			continue
		}
		if argType == uiContextRType {
			if webCall.UIContext == nil {
				return webErrorRtn(fmt.Errorf("missing UIContext for %s.%s", webCall.Service, webCall.Method))
			}
			valueArgs = append(valueArgs, reflect.ValueOf(*webCall.UIContext))
			continue
		}
		if argIdx >= len(webCall.Args) {
			return webErrorRtn(fmt.Errorf("not enough arguments passed %s.%s idx:%d (type %T)", webCall.Service, webCall.Method, idx, argType))
		}
		nativeArg, err := convertArgument(argType, webCall.Args[argIdx])
		if err != nil {
			return webErrorRtn(fmt.Errorf("cannot convert argument %s.%s type:%T idx:%d error:%v", webCall.Service, webCall.Method, argType, idx, err))
		}
		valueArgs = append(valueArgs, reflect.ValueOf(nativeArg))
		argIdx++
	}
	retValArr := method.Call(valueArgs)
	return convertReturnValues(retValArr)
}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Populate webCall.UIContext in the RPC request with the current block's UIContext (screen window id, block id) before calling
  2. If the call does not need block context, call a method variant that does not take UIContext
  3. In test/tooling code, construct a minimal valid UIContext instead of passing nil
  4. Inspect the method signature to confirm which parameter triggered the requirement (the first argType == uiContextRType encountered)

Example fix

// before
CallService(ctx, WebCallType{Service: "blockservice", Method: "...", Args: [...]})
// after
CallService(ctx, WebCallType{Service: "blockservice", Method: "...", Args: [...], UIContext: &uictx.UIContext{ScreenWinId: winId, BlockId: blockId}})
Defensive patterns

Strategy: validation

Validate before calling

function requireUIContext(call) {
  if (UI_CONTEXT_METHODS.has(call.Method) && (call.UIContext == null || call.UIContext.ScreenWinId == null)) {
    throw new Error(`${call.Service}.${call.Method} requires a UIContext`);
  }
}

Type guard

function hasUIContext(call): call is WebCallType & { UIContext: uictx.UIContext } {
  return call.UIContext != null && call.UIContext.ScreenWinId != null;
}

Try / catch

const rtn = CallService(ctx, call);
if (rtn.Error.includes("missing UIContext")) {
  // re-dispatch with UIContext from the current block
  return dispatchWithUIContext(call);
}

Prevention

When it happens

Trigger: Calling any service method whose signature includes a UIContext parameter (e.g. block-scoped operations) through CallService/handleService with webCall.UIContext left nil.

Common situations: Frontend RPC dispatch code paths that were written for context-free methods reused for UI-context methods; tests or tools calling services directly without building a UIContext; a protocol change where UIContext moved out of the WebCall payload.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/7da76f69a1e7fb04. Report an issue: GitHub.