wavetermdev/waveterm · error

reading input: %w

Error message

reading input: %w

What it means

While streaming the input, each reader.Read() error other than io.EOF aborts the transfer wrapped as "reading input". The library surfaces the underlying reader failure (stdin pipe, socket, or file read) instead of silently truncating the destination file.

Source

Thrown at cmd/wsh/cmd/wshcmd-file-util.go:70

	// First truncate the file with an empty write
	emptyWrite := fileData
	emptyWrite.Data64 = ""
	err := wshclient.FileWriteCommand(RpcClient, emptyWrite, &wshrpc.RpcOpts{Timeout: fileTimeout})
	if err != nil {
		return fmt.Errorf("initializing file with empty write: %w", err)
	}

	const chunkSize = wshrpc.FileChunkSize // 32KB chunks
	buf := make([]byte, chunkSize)
	totalWritten := int64(0)

	for {
		n, err := reader.Read(buf)
		if err == io.EOF {
			break
		}
		if err != nil {
			return fmt.Errorf("reading input: %w", err)
		}

		// Check total size
		totalWritten += int64(n)
		if totalWritten > MaxFileSize {
			return fmt.Errorf("input exceeds maximum file size of %d bytes", MaxFileSize)
		}

		// Prepare and send chunk
		chunk := buf[:n]
		appendData := fileData
		appendData.Data64 = base64.StdEncoding.EncodeToString(chunk)

		err = wshclient.FileAppendCommand(RpcClient, appendData, &wshrpc.RpcOpts{Timeout: int64(fileTimeout)})
		if err != nil {
			return fmt.Errorf("appending chunk to file: %w", err)
		}
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the wrapped inner error to identify the failing source (stdin, local file, or socket).
  2. Re-run the command after fixing the upstream producer in the pipe.
  3. Verify the source file is readable and not being concurrently modified.
  4. Note the destination file was already truncated — rewrite it fully after fixing the source.

Example fix

// before
generator-that-crashes | wsh cp - out.bin   # partial/failed
// after
generator-that-crashes > tmp.bin && wsh cp tmp.bin out.bin
Defensive patterns

Strategy: try-catch

Validate before calling

src, err := os.Open(localPath)
if err != nil {
    return fmt.Errorf("source unreadable before streaming: %w", err)
}
defer src.Close()

Try / catch

if err := streamWriteToFile(fileData, reader); err != nil {
    if strings.Contains(err.Error(), "reading input") {
        // note: destination already truncated; fix source and rewrite fully
    }
}

Prevention

When it happens

Trigger: reader.Read(buf) returns a non-EOF error during `wsh` streaming: broken stdin pipe, disk read error on the source file, or network reset when reading from a remote source.

Common situations: Upstream producer in a pipe crashed (SIGPIPE/broken pipe); reading from a file that was truncated or became unreadable mid-transfer; network hiccup during remote streaming.

Related errors


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