wavetermdev/waveterm · error
stream file protocol error, directory entry has data
Error message
stream file protocol error, directory entry has data
What it means
When streaming a directory, each packet should contain directory entries and no payload data. ReadFileStream rejects a directory packet that carries Data64, since directory listings must not include file content — a protocol violation by the remote responder.
Source
Thrown at pkg/remote/fileshare/fsutil/fsutil.go:105
if firstPk {
firstPk = false
// first packet has the fileinfo
if resp.Info == nil {
return fmt.Errorf("stream file protocol error, first pk fileinfo is empty")
}
fileData = &resp
if fileData.Info.IsDir {
isDir = true
}
fileInfoCallback(*fileData.Info)
continue
}
if isDir {
if len(resp.Entries) == 0 {
continue
}
if resp.Data64 != "" {
return fmt.Errorf("stream file protocol error, directory entry has data")
}
if err := dirCallback(resp.Entries); err != nil {
return err
}
} else {
if resp.Data64 == "" {
continue
}
decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewReader([]byte(resp.Data64)))
if err := fileCallback(decoder); err != nil {
return err
}
}
}
}
}
func ReadStreamToFileData(ctx context.Context, readCh <-chan wshrpc.RespOrErrorUnion[wshrpc.FileData]) (*wshrpc.FileData, error) {View on GitHub (pinned to a4447c1563)
Solutions
- Ensure client and remote wsh versions match and are current
- Restart the file stream — desynced streams cannot recover mid-stream
- List the directory entries individually instead of streaming as one call
- Report/inspect the remote responder implementation if reproducible
Example fix
// before
data, err := fsutil.ReadStreamToFileData(ctx, ctl, dirPath) // dir packet has data
// after
if isRemoteDir(ctx, ctl, dirPath) {
err = streamDirEntriesOnly(ctx, ctl, dirPath) // entries-only streaming path
} else {
data, err = fsutil.ReadStreamToFileData(ctx, ctl, dirPath)
} Defensive patterns
Strategy: type-guard
Validate before calling
fi, _ := remoteStat(ctx, ctl, path)
if fi != nil && fi.IsDir {
// use the directory streaming path, not the file-data path
} Type guard
func isDirPacketOk(resp fileshare.StreamResponse) bool {
return resp.Info != nil && !resp.Info.IsDir || (resp.Info.IsDir && resp.Data64 == "")
} Try / catch
_, err := fsutil.ReadStreamToFileData(ctx, ctl, dir)
if err != nil && strings.Contains(err.Error(), "directory entry has data") {
return fmt.Errorf("remote protocol mismatch — upgrade wsh on both ends")
} Prevention
- Keep wsh versions identical on client and remote
- Use entries-only streaming for directories
- Restart streams from scratch after any protocol error
When it happens
Trigger: ReadStreamToFileData on a directory where the remote sends entries together with non-empty Data64 — e.g. a mismatched fileshare implementation or corrupted stream framing.
Common situations: Version mismatch between client and remote wsh protocol; remote bug sending file-style packets for directories; stream desync after a prior packet error.
Related errors
- stream file protocol error, first pk fileinfo is empty
- stream file protocol error, no file info
- failed to copy data: %w
- beginning of file
- procinfo: process not found
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/1e98e9f6691d9d5f.
Report an issue: GitHub.