alibaba/arthas · error · IllegalStateException
Cannot write to standard output when {}
Error message
Cannot write to standard output when {} What it means
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.
Source
Thrown at labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/grpc/observer/impl/ArthasStreamObserverImpl.java:154
}
@Override
public void end(int statusCode, String message) {
terminate(statusCode, message);
}
@Override
public ArthasStreamObserver write(String msg) {
ResponseBody result = ResponseBody.newBuilder().setStringValue(msg).build();
onNext((T) result);
return this;
}
@Override
public void appendResult(ResultModel result) {
if (process.status() != ExecStatus.RUNNING) {
throw new IllegalStateException(
"Cannot write to standard output when " + process.status().name().toLowerCase());
}
result.setJobId(jobId);
if (resultDistributor != null) {
resultDistributor.appendResult(result);
}
}
@Override
public int getJobId() {
return jobId;
}
@Override
public Object getRequestModel() {
return requestModel;
}
@OverrideView on GitHub (pinned to 21cf2e9ba5)
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.
Example fix
// before: async callback appends after termination
process.end(0);
observer.appendResult(lateResult); // throws
// after: append before ending, or guard
if (process.status() == ExecStatus.RUNNING) {
observer.appendResult(lateResult);
}
process.end(0); Defensive patterns
Strategy: validation
Validate before calling
if (process.status() == ExecStatus.RUNNING) {
observer.appendResult(result);
} else {
log.debug("Skipping appendResult — process is {}", process.status());
} Type guard
import com.taobao.arthas.core.shell.system.ExecStatus;
public boolean isProcessRunning(Process process) {
return process != null && process.status() == ExecStatus.RUNNING;
} Try / catch
try {
observer.appendResult(result);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Cannot write to standard output")) {
// process already ended — buffer or drop the result
log.warn("Dropped result, process not running: {}", process.status());
} else { throw e; }
} Prevention
- Ensure all results are appended before calling end()/terminate().
- Guard async result-emission with a process-status check.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- AllServerStart must be initialized before!
- Cannot interrupt process in {} state
- Cannot resume process in {} state
- Cannot suspend process in {} state
- Cannot set to background a process in {} state
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/e175ea5ac6d726e1.
Report an issue: GitHub.