vxcontrol/pentagi · error

listing output exceeded %d bytes

Error message

listing output exceeded %d bytes

What it means

demuxExecStdout enforces a hard cap (maxListStdoutBytes) on accumulated stdout so a compromised or noisy sandbox cannot stream unbounded output into memory. As soon as the stdout buffer exceeds the cap, it aborts with this error. The listing is discarded entirely — the cap is a safety limit, not a truncation mechanism (truncation of entry COUNT is handled separately via Truncated).

Source

Thrown at backend/pkg/docker/client.go:1083

			if err == io.EOF {
				break // clean end at a frame boundary
			}
			// A header cut short (ErrUnexpectedEOF) means the stream was truncated
			// mid-frame — the listing is incomplete, so fail rather than silently
			// dropping the tail.
			return nil, fmt.Errorf("truncated exec stream: %w", err)
		}
		size := int64(binary.BigEndian.Uint32(header[4:8]))
		if size == 0 {
			continue
		}
		switch header[0] {
		case 1: // stdout
			if _, err := io.CopyN(&stdout, r, size); err != nil {
				return nil, err
			}
			if stdout.Len() > maxStdout {
				return nil, fmt.Errorf("listing output exceeded %d bytes", maxStdout)
			}
		case 3: // systemerr — a daemon-level error injected mid-stream; surface it
			var msg bytes.Buffer
			_, _ = io.CopyN(&msg, r, size)
			return nil, fmt.Errorf("docker exec systemerr: %s", strings.TrimSpace(msg.String()))
		default: // stderr and anything else — discard
			if _, err := io.CopyN(io.Discard, r, size); err != nil {
				return nil, err
			}
		}
	}
	return stdout.Bytes(), nil
}

type statFailure struct {
	name string
	err  error
}

View on GitHub (pinned to ea665308ba)

Solutions

  1. List a more specific subdirectory instead of a huge parent
  2. If large listings are legitimate for your workload, raise maxListStdoutBytes
  3. Handle the error in the caller by suggesting the user navigate deeper rather than listing everything at once
  4. Pre-aggregate: enumerate subdirs of interest rather than the root

Example fix

// before
listing, err := dc.ListContainerDir(ctx, id, "/usr")
// after: target the relevant subtree
listing, err := dc.ListContainerDir(ctx, id, "/usr/local/bin")
Defensive patterns

Strategy: validation

Validate before calling

// estimate listing size first via a cheap exec
out, _ := runInContainer(ctx, containerID,
    []string{"sh", "-c", "find " + dir + " -maxdepth 1 -mindepth 1 | wc -l"})
if n, _ := strconv.Atoi(strings.TrimSpace(out)); n > 50000 {
    return fmt.Errorf("directory %s too large to list in one call", dir)
}

Try / catch

listing, err := client.ListContainerDir(ctx, containerID, dir)
if err != nil && strings.Contains(err.Error(), "listing output exceeded") {
    // fall back to listing subdirectories incrementally
    return listInChunks(ctx, containerID, dir)
}

Prevention

When it happens

Trigger: Listing a directory whose `find -maxdepth 1 -print0` output exceeds maxListStdoutBytes — i.e., a very large number of children or extremely long path names (deeply nested container paths).

Common situations: Pointing the listing at /, /usr, /proc, node_modules, or container-internal dirs with tens of thousands of entries; paths near PATH_MAX multiplied by thousands of entries.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/6fe19f1d269fbb63. Report an issue: GitHub.