vxcontrol/pentagi · error
failed to read file '%s' content: %w
Error message
failed to read file '%s' content: %w
What it means
After allocating fileContent of tarHeader.Size bytes, the code reads the tar entry body; any read error other than io.EOF (which is normal for exact-size reads) is wrapped with this message. io.EOF is intentionally accepted because tar.Reader returns EOF exactly when the full entry was consumed, so this error means the stream died mid-entry.
Source
Thrown at backend/pkg/tools/terminal.go:415
buffer.WriteString(
fmt.Sprintf("'%s' file content (with size %d bytes) shown below:\n",
tarHeader.Name, tarHeader.Size,
),
)
}
const maxReadFileSize int64 = 100 * 1024 * 1024 // 100 MB limit
if tarHeader.Size > maxReadFileSize {
return "", fmt.Errorf("file '%s' size %d exceeds maximum allowed size %d", tarHeader.Name, tarHeader.Size, maxReadFileSize)
}
if tarHeader.Size < 0 {
return "", fmt.Errorf("file '%s' has invalid size %d", tarHeader.Name, tarHeader.Size)
}
var fileContent = make([]byte, tarHeader.Size)
_, err = tarReader.Read(fileContent)
if err != nil && err != io.EOF {
return "", fmt.Errorf("failed to read file '%s' content: %w", tarHeader.Name, err)
}
buffer.Write(fileContent)
if stats.Mode.IsDir() {
buffer.WriteString("\n\n")
}
}
return buffer.String(), nil
}
func (t *terminal) WriteFile(ctx context.Context, flowID int64, content string, path string) (string, error) {
if path == "" {
return "", fmt.Errorf("path is required and cannot be empty")
}
if err := t.writeFileToContainer(ctx, flowID, path, content); err != nil {
return "", errView on GitHub (pinned to ea665308ba)
Solutions
- Retry the entire read (CopyFromContainer + tar loop) — mid-stream truncation is usually transient
- Use errors.Is(err, io.ErrUnexpectedEOF) to distinguish truncation from other IO errors and log accordingly
- Check Docker daemon logs and host disk health (`dmesg`, `docker info`) when it recurs
- For large files, stream with io.CopyFull / io.ReadFull into the buffer with timeouts instead of a single Read
Example fix
// before
_, err = tarReader.Read(fileContent)
if err != nil && err != io.EOF {
return "", fmt.Errorf("failed to read file '%s' content: %w", tarHeader.Name, err)
}
// after
if _, err := io.ReadFull(tarReader, fileContent); err != nil && err != io.EOF && !errors.Is(err, io.ErrUnexpectedEOF) {
return "", fmt.Errorf("failed to read file '%s' content: %w", tarHeader.Name, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-call: confirm daemon connectivity to reduce mid-stream failures
if _, err := dockerClient.Ping(ctx); err != nil {
return fmt.Errorf("docker daemon unstable: %w", err)
} Type guard
func isMidStreamIO(err error) bool {
return err != nil && !errors.Is(err, io.EOF) && (errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, syscall.ECONNRESET) || errors.Is(err, syscall.EPIPE))
} Try / catch
content, err := tool.ReadFile(ctx, flowID, path)
if err != nil && strings.Contains(err.Error(), "failed to read file") {
if isRetryable(err) {
content, err = tool.ReadFile(ctx, flowID, path) // one retry
}
} Prevention
- Use io.ReadFull instead of a single Read for exact-size tar entries
- Retry mid-stream failures; they are usually transient
- Monitor Docker host disk/memory health
- Avoid removing or restarting the container during an in-flight copy
When it happens
Trigger: The tar stream from CopyFromContainer terminates before tarHeader.Size bytes are delivered — connection reset to a remote daemon, daemon restart, reader closed by timeout, or disk/IO error on the Docker host while assembling the archive.
Common situations: Reading a large file from a container on a remote/unstable Docker host; host under memory pressure killing the daemon mid-copy; container removed or restarted concurrently with the copy; misconfigured proxy between client and daemon cutting long-lived streams.
Related errors
- image download stream processing failed: %w
- failed to read tar entry: %w
- failed to copy output: %w
- failed to copy file: %w
- failed to read tar header: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/1bcd34f4bfe8d96f.
Report an issue: GitHub.