{"record":{"id":"32104e5fcf9dccef","repo":"babalae/better-genshin-impact","slug":"webview-webview","errorCode":null,"errorMessage":"WebView 不能向其他 WebView 发送消息。","messagePattern":"WebView 不能向其他 WebView 发送消息。","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"warning","filePath":"BetterGenshinImpact/Service/Instance/InstanceService.cs","lineNumber":205,"sourceCode":"        EnsureSuccessfulResponse(response);\n        return response.Data?.ToObject<WebViewListResponse>(InstanceIpcProtocol.Serializer)\n                   ?.Endpoints\n               ?? [];\n    }\n\n    public async Task SendWebViewMessageAsync(\n        int targetProcessId,\n        string operation,\n        JToken? data = null,\n        CancellationToken cancellationToken = default)\n    {\n        if (string.IsNullOrWhiteSpace(operation))\n        {\n            throw new ArgumentException(\"WebView 操作名称不能为空。\", nameof(operation));\n        }\n        if (Context.InstanceType == BetterGiInstanceType.WebView)\n        {\n            throw new InvalidOperationException(\"WebView 不能向其他 WebView 发送消息。\");\n        }\n\n        if (Context.InstanceType == BetterGiInstanceType.Primary)\n        {\n            if (!_messageState.WebViewConnectionsByProcessId.TryGetValue(\n                    targetProcessId,\n                    out var target))\n            {\n                throw new InvalidOperationException(\n                    $\"WebView 进程 {targetProcessId} 当前不在线。\");\n            }\n\n            var targetResponse = await target.Connection.SendRequestAsync(\n                InstanceOperations.WebViewMessage,\n                new WebViewMessage\n                {\n                    SourceProcessId = Context.ProcessId,\n                    Operation = operation,","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Service/Instance/InstanceService.cs#L187-L223","documentation":"Thrown by SendWebViewMessageAsync when Context.InstanceType == BetterGiInstanceType.WebView. The IPC topology is star-shaped: only Primary and ChildSession instances can originate WebView messages (Primary sends directly, ChildSession routes through Primary). A WebView instance is a leaf node that receives messages but cannot send to other WebViews or originate messages.","triggerScenarios":"Code running inside a WebView-type BetterGI process calls SendWebViewMessageAsync. The WebView instance type is assigned by the root during connection.open when the process boots as a WebView helper. This is an architectural constraint enforced at the API boundary.","commonSituations":"A code path shared between Primary and WebView instances that unconditionally calls SendWebViewMessageAsync without checking the instance type; a misconfigured launch that started as WebView when it should have been Primary or ChildSession; test code running against a WebView-mode instance.","solutions":["Guard the call site with a check on Context.InstanceType before invoking SendWebViewMessageAsync.","Verify the process was launched with the correct instance type — check command-line arguments and InstanceBootstrap.Initialize logic that determines the requested type.","If the WebView needs to communicate back to Primary, use a different mechanism (e.g., the response to an incoming WebViewMessage request, not an outbound SendWebViewMessageAsync)."],"exampleFix":"// before\nawait instanceService.SendWebViewMessageAsync(targetPid, operation, data);\n\n// after\nif (instanceService.Context.InstanceType == BetterGiInstanceType.WebView)\n{\n    _logger.LogWarning(\"WebView 实例不能发送 WebView 消息，已跳过：{Operation}\", operation);\n    return;\n}\nawait instanceService.SendWebViewMessageAsync(targetPid, operation, data);","handlingStrategy":"validation","validationCode":"// Check instance type before calling\nif (instanceService.Context.InstanceType != BetterGiInstanceType.WebView)\n{\n    await instanceService.SendWebViewMessageAsync(pid, operation, data);\n}","typeGuard":"// Type guard for send-capable instances\nstatic bool CanSendWebViewMessages(BetterGiInstanceType type)\n    => type != BetterGiInstanceType.WebView;","tryCatchPattern":null,"preventionTips":["Check Context.InstanceType before calling SendWebViewMessageAsync in shared code paths.","Ensure the process is launched with the correct instance type.","WebView instances should respond to incoming messages, not originate outbound ones."],"tags":["api-contract","webview","instance-type","topology"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}