{"record":{"id":"7da76f69a1e7fb04","repo":"wavetermdev/waveterm","slug":"missing-uicontext-for-s-s","errorCode":null,"errorMessage":"missing UIContext for %s.%s","messagePattern":"missing UIContext for (.+?)\\.(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/service/service.go","lineNumber":336,"sourceCode":"\tsvcObj := ServiceMap[webCall.Service]\n\tif svcObj == nil {\n\t\treturn webErrorRtn(fmt.Errorf(\"invalid service: %q\", webCall.Service))\n\t}\n\tmethod := reflect.ValueOf(svcObj).MethodByName(webCall.Method)\n\tif !method.IsValid() {\n\t\treturn webErrorRtn(fmt.Errorf(\"invalid method: %s.%s\", webCall.Service, webCall.Method))\n\t}\n\tvar valueArgs []reflect.Value\n\targIdx := 0\n\tfor idx := 0; idx < method.Type().NumIn(); idx++ {\n\t\targType := method.Type().In(idx)\n\t\tif idx == 0 && argType == contextRType {\n\t\t\tvalueArgs = append(valueArgs, reflect.ValueOf(ctx))\n\t\t\tcontinue\n\t\t}\n\t\tif argType == uiContextRType {\n\t\t\tif webCall.UIContext == nil {\n\t\t\t\treturn webErrorRtn(fmt.Errorf(\"missing UIContext for %s.%s\", webCall.Service, webCall.Method))\n\t\t\t}\n\t\t\tvalueArgs = append(valueArgs, reflect.ValueOf(*webCall.UIContext))\n\t\t\tcontinue\n\t\t}\n\t\tif argIdx >= len(webCall.Args) {\n\t\t\treturn webErrorRtn(fmt.Errorf(\"not enough arguments passed %s.%s idx:%d (type %T)\", webCall.Service, webCall.Method, idx, argType))\n\t\t}\n\t\tnativeArg, err := convertArgument(argType, webCall.Args[argIdx])\n\t\tif err != nil {\n\t\t\treturn webErrorRtn(fmt.Errorf(\"cannot convert argument %s.%s type:%T idx:%d error:%v\", webCall.Service, webCall.Method, argType, idx, err))\n\t\t}\n\t\tvalueArgs = append(valueArgs, reflect.ValueOf(nativeArg))\n\t\targIdx++\n\t}\n\tretValArr := method.Call(valueArgs)\n\treturn convertReturnValues(retValArr)\n}\n","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/service/service.go#L318-L354","documentation":"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.","triggerScenarios":"Calling any service method whose signature includes a UIContext parameter (e.g. block-scoped operations) through CallService/handleService with webCall.UIContext left nil.","commonSituations":"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.","solutions":["Populate webCall.UIContext in the RPC request with the current block's UIContext (screen window id, block id) before calling","If the call does not need block context, call a method variant that does not take UIContext","In test/tooling code, construct a minimal valid UIContext instead of passing nil","Inspect the method signature to confirm which parameter triggered the requirement (the first argType == uiContextRType encountered)"],"exampleFix":"// before\nCallService(ctx, WebCallType{Service: \"blockservice\", Method: \"...\", Args: [...]})\n// after\nCallService(ctx, WebCallType{Service: \"blockservice\", Method: \"...\", Args: [...], UIContext: &uictx.UIContext{ScreenWinId: winId, BlockId: blockId}})","handlingStrategy":"validation","validationCode":"function requireUIContext(call) {\n  if (UI_CONTEXT_METHODS.has(call.Method) && (call.UIContext == null || call.UIContext.ScreenWinId == null)) {\n    throw new Error(`${call.Service}.${call.Method} requires a UIContext`);\n  }\n}","typeGuard":"function hasUIContext(call): call is WebCallType & { UIContext: uictx.UIContext } {\n  return call.UIContext != null && call.UIContext.ScreenWinId != null;\n}","tryCatchPattern":"const rtn = CallService(ctx, call);\nif (rtn.Error.includes(\"missing UIContext\")) {\n  // re-dispatch with UIContext from the current block\n  return dispatchWithUIContext(call);\n}","preventionTips":["Pass UIContext from the active block whenever dispatching from a block context","Keep a list of service methods that require UIContext (check signatures for uictx.UIContext params)","Centralize RPC dispatch in one helper that always attaches the current UIContext when available"],"tags":["rpc","uicontext","arguments"],"backgroundTag":"missing-uicontext","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}