vxcontrol/pentagi · error

failed to stat container path '%s': %w

Error message

failed to stat container path '%s': %w

What it means

ListContainerDir first stats the target directory inside the container; if ContainerStatPath fails, the error is wrapped with this message including the path that could not be stat'ed. Nothing was listed.

Source

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

	Files    []container.PathStat
	Failures []ContainerEntryError
	// Truncated is set when the directory held more than maxListEntries children
	// and only the first maxListEntries were listed.
	Truncated bool
}

func (dc *dockerClient) ListContainerDir(
	ctx context.Context,
	containerID string,
	dirPath string,
) (ContainerDirListing, error) {
	if strings.TrimSpace(dirPath) == "" {
		dirPath = WorkFolderPathInContainer
	}

	dirStat, err := dc.ContainerStatPath(ctx, containerID, dirPath)
	if err != nil {
		return ContainerDirListing{}, fmt.Errorf("failed to stat container path '%s': %w", dirPath, err)
	}
	if !dirStat.Mode.IsDir() {
		return ContainerDirListing{}, fmt.Errorf("container path '%s' is not a directory", dirPath)
	}

	// List direct children NUL-delimited. Parsing `ls` output is unsafe: under a
	// TTY GNU coreutils shell-quotes names and busybox wraps them in ANSI escapes,
	// so a readable file with a space / quote / non-ASCII byte would be mis-stat'd
	// and reported unreadable. `find -print0` emits literal bytes and is portable
	// (GNU + busybox); the NUL delimiter also survives names containing newlines.
	// No TTY: a TTY's onlcr would rewrite every \n in the stream to \r\n —
	// including a \n that is part of a filename — corrupting the name. Without a
	// TTY the exec stream is multiplexed and demuxed below.
	createResp, err := dc.ContainerExecCreate(ctx, containerID, client.ExecCreateOptions{
		Cmd:          []string{"find", dirPath, "-maxdepth", "1", "-mindepth", "1", "!", "-name", ".*", "-print0"},
		AttachStdout: true,
		AttachStderr: true,
	})

View on GitHub (pinned to ea665308ba)

Solutions

  1. Verify the container is running (`IsContainerRunning`) before listing
  2. Confirm the path exists: `docker exec <id> ls -la <dir>` and correct the path argument
  3. Check the image contains the utilities the stat implementation exec's; use a fuller base image if not
  4. Normalize/trim the incoming dirPath (strip quotes, trailing slashes) before calling ListContainerDir

Example fix

// before
listing, err := c.ListContainerDir(ctx, containerID, dirPath)
// after
if strings.TrimSpace(dirPath) == "" {
    dirPath = WorkFolderPathInContainer
}
dirPath = strings.Trim(dirPath, "\"'")
listing, err := c.ListContainerDir(ctx, containerID, dirPath)
Defensive patterns

Strategy: validation

Validate before calling

func sanitizeDirPath(p string) string {
    p = strings.TrimSpace(p)
    p = strings.Trim(p, "\"'")
    p = strings.TrimRight(p, "/")
    if p == "" {
        p = WorkFolderPathInContainer
    }
    return p
}

Try / catch

listing, err := c.ListContainerDir(ctx, id, dir)
if err != nil {
    if strings.Contains(err.Error(), "failed to stat container path") {
        // surface the path back to the agent so it can correct it
        return fmt.Errorf("path %q not accessible in container", dir)
    }
    return err
}

Prevention

When it happens

Trigger: dc.ContainerStatPath fails: the path does not exist inside the container, the container is not running, the container lacks the binaries needed to run the stat command, or command execution in the container failed (exec create/start error).

Common situations: Agent requests a path that was deleted or never created in the sandbox; container stopped/crashed before the listing; minimal images (distroless) where the exec shell/tooling is unavailable; typo'd or shell-quoted path coming from LLM tool arguments; wrong WorkFolderPathInContainer assumption for a custom image.

Related errors


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