{"record":{"id":"e175ea5ac6d726e1","repo":"alibaba/arthas","slug":"cannot-write-to-standard-output-when","errorCode":null,"errorMessage":"Cannot write to standard output when {}","messagePattern":"Cannot write to standard output when (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/grpc/observer/impl/ArthasStreamObserverImpl.java","lineNumber":154,"sourceCode":"    }\n\n    @Override\n    public void end(int statusCode, String message) {\n        terminate(statusCode, message);\n    }\n\n\n    @Override\n    public ArthasStreamObserver write(String msg) {\n        ResponseBody result = ResponseBody.newBuilder().setStringValue(msg).build();\n        onNext((T) result);\n        return this;\n    }\n\n    @Override\n    public void appendResult(ResultModel result) {\n        if (process.status() != ExecStatus.RUNNING) {\n            throw new IllegalStateException(\n                    \"Cannot write to standard output when \" + process.status().name().toLowerCase());\n        }\n        result.setJobId(jobId);\n        if (resultDistributor != null) {\n            resultDistributor.appendResult(result);\n        }\n    }\n    @Override\n    public int getJobId() {\n        return jobId;\n    }\n\n    @Override\n    public Object getRequestModel() {\n        return requestModel;\n    }\n\n    @Override","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/grpc/observer/impl/ArthasStreamObserverImpl.java#L136-L172","documentation":"ArthasStreamObserverImpl.appendResult() throws IllegalStateException when the backing process is not in ExecStatus.RUNNING state. Results can only be appended to the output stream while the command process is actively running; appending after it has terminated, finished, or been cancelled corrupts the result pipeline.","triggerScenarios":"Calling appendResult(resultModel) after process.status() has transitioned to TERMINATED, FINISHED, or any non-RUNNING state — e.g. writing results from an async callback that fires after the process ended.","commonSituations":"A background thread or gRPC callback tries to push results after the command process already terminated; a race between process termination and a late result emission; explicit end() was called before all results were appended.","solutions":["Ensure all result-appending completes before calling end()/terminate() on the process.","Guard appendResult calls with a check: if (process.status() == ExecStatus.RUNNING) before appending.","Fix the race by synchronizing result emission with process lifecycle transitions."],"exampleFix":"// before: async callback appends after termination\nprocess.end(0);\nobserver.appendResult(lateResult); // throws\n\n// after: append before ending, or guard\nif (process.status() == ExecStatus.RUNNING) {\n    observer.appendResult(lateResult);\n}\nprocess.end(0);","handlingStrategy":"validation","validationCode":"if (process.status() == ExecStatus.RUNNING) {\n    observer.appendResult(result);\n} else {\n    log.debug(\"Skipping appendResult — process is {}\", process.status());\n}","typeGuard":"import com.taobao.arthas.core.shell.system.ExecStatus;\npublic boolean isProcessRunning(Process process) {\n    return process != null && process.status() == ExecStatus.RUNNING;\n}","tryCatchPattern":"try {\n    observer.appendResult(result);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Cannot write to standard output\")) {\n        // process already ended — buffer or drop the result\n        log.warn(\"Dropped result, process not running: {}\", process.status());\n    } else { throw e; }\n}","preventionTips":["Ensure all results are appended before calling end()/terminate().","Guard async result-emission with a process-status check."],"tags":["arthas","grpc-web-proxy","lifecycle","concurrency","process-state"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}