wavetermdev/waveterm · error

writing file: %w

Error message

writing file: %w

What it means

wsh file write wraps any error returned by the FileWriteCommand RPC (which streams the base64-encoded file data to the Wave block/server) with 'writing file: %w'. It indicates the remote write failed after the client already validated the 10MB MaxFileSize limit. Common causes are RPC timeouts (fileTimeout), connection loss to the block, or a server-side write failure (permissions, disk full, invalid path).

Source

Thrown at cmd/wsh/cmd/wshcmd-file.go:261

	if err != nil {
		return err
	}
	fileData := wshrpc.FileData{
		Info: &wshrpc.FileInfo{
			Path: path}}

	limitReader := io.LimitReader(WrappedStdin, MaxFileSize+1)
	data, err := io.ReadAll(limitReader)
	if err != nil {
		return fmt.Errorf("reading input: %w", err)
	}
	if len(data) > MaxFileSize {
		return fmt.Errorf("input exceeds maximum file size of %d bytes", MaxFileSize)
	}
	fileData.Data64 = base64.StdEncoding.EncodeToString(data)
	err = wshclient.FileWriteCommand(RpcClient, fileData, &wshrpc.RpcOpts{Timeout: fileTimeout})
	if err != nil {
		return fmt.Errorf("writing file: %w", err)
	}

	return nil
}

func fileAppendRun(cmd *cobra.Command, args []string) error {
	path, err := fixRelativePaths(args[0])
	if err != nil {
		return err
	}
	fileData := wshrpc.FileData{
		Info: &wshrpc.FileInfo{
			Path: path}}

	info, err := ensureFile(fileData)
	if err != nil {
		return err
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check connectivity to the target block/tab and rerun the command
  2. Increase --timeout (fileTimeout) if the file is large or the connection is slow
  3. Verify the destination path exists and is writable on the remote
  4. Confirm the file is under the 10MB MaxFileSize before writing

Example fix

// before
if err != nil {
    return fmt.Errorf("writing file: %w", err)
}
// after
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        return fmt.Errorf("writing file: rpc timed out, try a longer --timeout: %w", err)
    }
    return fmt.Errorf("writing file: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

info, err := os.Stat(localPath)
if err != nil { return err }
if info.Size() >= 10*1024*1024 {
    return fmt.Errorf("%s exceeds the 10MB write limit", localPath)
}

Type guard

func isTimeoutErr(err error) bool {
    return errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled)
}

Try / catch

err := fileWriteRun(cmd, args)
var rpcErr *wshrpc.RpcError
if errors.As(err, &rpcErr) {
    // handle RPC-level failure (retry with longer timeout)
} else if err != nil {
    // surface wrapped cause: fmt.Sprintf("%+v", errors.Unwrap(err))
}

Prevention

When it happens

Trigger: Running 'wsh file write [block] <file>' where the underlying wshclient.FileWriteCommand returns an error: RPC timeout, no router/connection to the target block, remote path not writable, or disk full on the remote.

Common situations: Writing a large file (~10MB, near the limit) so the RPC hits fileTimeout; targeting a block that has closed or disconnected; writing to a path without permissions on the remote machine.

Related errors


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