wavetermdev/waveterm · error

reading terminal output: %w

Error message

reading terminal output: %w

What it means

debugTermRun calls wshclient.DebugTermCommand with a 2000ms timeout to fetch raw terminal output for the given block. Any RPC failure — timeout, disconnected client, unknown block, backend error — is wrapped as 'reading terminal output'.

Source

Thrown at cmd/wsh/cmd/wshcmd-debugterm.go:103

			WriteStdout("%s", formatDebugTermDecode(termData))
		} else {
			WriteStdout("%s", formatDebugTermHex(termData))
		}
		return nil
	}
	if debugTermSize <= 0 {
		return fmt.Errorf("size must be greater than 0")
	}
	fullORef, err := resolveBlockArg()
	if err != nil {
		return err
	}
	rtn, err := wshclient.DebugTermCommand(RpcClient, wshrpc.CommandDebugTermData{
		BlockId: fullORef.OID,
		Size:    debugTermSize,
	}, &wshrpc.RpcOpts{Timeout: 2000})
	if err != nil {
		return fmt.Errorf("reading terminal output: %w", err)
	}
	termData, err := base64.StdEncoding.DecodeString(rtn.Data64)
	if err != nil {
		return fmt.Errorf("decoding terminal output: %w", err)
	}
	var output string
	if mode == DebugTermModeDecode {
		output = formatDebugTermDecode(termData)
	} else {
		output = formatDebugTermHex(termData)
	}
	WriteStdout("%s", output)
	return nil
}

func debugTermPreRun(cmd *cobra.Command, args []string) error {
	if debugTermStdin || debugTermInput != "" {
		return nil

View on GitHub (pinned to a4447c1563)

Solutions

  1. Confirm the block id resolves to a live terminal block (use `wsh ls` / block list)
  2. Retry with a freshly connected wsh session (re-run inside the Wave tab)
  3. Retry the command — a transient timeout may succeed on a second attempt
  4. Verify the Wave app is running and the connection is healthy

Example fix

// before
wsh debugterm 8f2a... --size 4096   # block was closed
// after
# re-open the terminal, get its current block id, then:
wsh debugterm <current-blockid> --size 4096
Defensive patterns

Strategy: retry

Validate before calling

// ensure the block exists and is a terminal before the RPC:
meta, err := wshclient.GetMetaCommand(RpcClient, fullORef.OID, nil)
if err != nil || meta["view"] != "term" {
	return fmt.Errorf("block %s is not a live terminal", fullORef.OID)
}

Try / catch

rtn, err := wshclient.DebugTermCommand(RpcClient, data, &wshrpc.RpcOpts{Timeout: 2000})
if err != nil {
	if ctxErr := context.DeadlineExceeded; errors.Is(err, ctxErr) || strings.Contains(err.Error(), "timeout") {
		// retry once with a longer timeout
		rtn, err = wshclient.DebugTermCommand(RpcClient, data, &wshrpc.RpcOpts{Timeout: 10000})
	}
	if err != nil {
		return fmt.Errorf("reading terminal output: %w", err)
	}
}

Prevention

When it happens

Trigger: The target block does not exist or is not a terminal; the RPC exceeds the 2-second timeout; the wsh connection to the Wave app is broken; the backend returns an error reading the term buffer.

Common situations: Passing a blockId/oref of a non-terminal block (editor/web); the terminal was closed between resolving the block and the RPC; slow/laggy Wave connection exceeding the 2s timeout; stale JWT after app restart.

Related errors


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