vxcontrol/pentagi · error

invalid path component '%s': %w

Error message

invalid path component '%s': %w

What it means

After normalization, SanitizeContainerCachePath splits the path on '/' and runs each component through validatePathComponent. This error wraps the per-component failure, identifying the offending component (e.g. one containing '..', an unsupported character, or being too long) with the underlying reason.

Source

Thrown at backend/pkg/flowfiles/files.go:149

}

func SanitizeContainerCachePath(containerPath string) (string, error) {
	trimmedPath := strings.TrimSpace(containerPath)
	if trimmedPath == "" {
		return "", fmt.Errorf("path is required")
	}

	normalizedPath := strings.ReplaceAll(trimmedPath, "\\", "/")
	cleanPath := strings.TrimPrefix(path.Clean("/"+normalizedPath), "/")
	if cleanPath == "." || cleanPath == "" {
		return "", fmt.Errorf("invalid path")
	}

	parts := strings.Split(cleanPath, "/")
	for i, part := range parts {
		cleanPart, err := validatePathComponent(part)
		if err != nil {
			return "", fmt.Errorf("invalid path component '%s': %w", part, err)
		}
		parts[i] = cleanPart
	}

	return path.Join(parts...), nil
}

func validatePathComponent(component string) (string, error) {
	cleanName := strings.TrimSpace(component)
	if cleanName == "." || cleanName == ".." || cleanName == "/" || cleanName == "" {
		return "", fmt.Errorf("invalid file name")
	}
	if len(cleanName) > MaxFileNameLength {
		return "", fmt.Errorf("file name is too long")
	}
	for _, r := range cleanName {
		if r < 0x20 || r == 0x7f {
			return "", fmt.Errorf("file name contains control characters")

View on GitHub (pinned to ea665308ba)

Solutions

  1. Read the wrapped component and reason in the message, then correct that specific segment in the source of the path.
  2. Reject or re-ask the agent/user when the path contains '..', ':', '*', '?', '"', '<', '>', '|', backslashes (converted to '/' but still disallowed inside a single segment), or control characters.
  3. Pre-validate with the same rules before calling: split the normalized path and check each segment for length ≤255 and absence of forbidden characters.

Example fix

// before
pullFiles(containerPath: "logs/../../etc/passwd")
// after
pullFiles(containerPath: "logs/app.log")
Defensive patterns

Strategy: validation

Validate before calling

func prevalidatePath(p string) error {
    for _, part := range strings.Split(strings.ReplaceAll(p, "\\", "/"), "/") {
        if part == "." || part == ".." || strings.TrimSpace(part) == "" {
            return fmt.Errorf("bad component %q", part)
        }
        if len(part) > 255 {
            return fmt.Errorf("component %q too long", part)
        }
        for _, r := range part {
            if r < 0x20 || r == 0x7f {
                return fmt.Errorf("control char in %q", part)
            }
            if strings.ContainsRune("/:*?\"<>|", r) && r != '/' {
                return fmt.Errorf("unsupported char %q in %q", r, part)
            }
        }
    }
    return nil
}

Type guard

func isSafeComponent(s string) bool {
    return s != "." && s != ".." && s != "" && len(s) <= 255 &&
        !strings.ContainsAny(s, "/:*?\"<>|")
}

Try / catch

if err != nil {
    if strings.HasPrefix(err.Error(), "invalid path component") {
        var comp string
        fmt.Sscanf(err.Error(), "invalid path component '%s':", &comp)
        return fmt.Errorf("bad segment %q in container path", comp)
    }
    return err
}

Prevention

When it happens

Trigger: Any path segment that fails validatePathComponent: a segment equal to "." or ".." (e.g. "logs/../../etc/passwd"), a segment containing one of : * ? " < > | (e.g. "C:file", "a*b.txt"), a segment longer than 255 bytes, an empty segment after cleaning (e.g. "a//b" yields no empty split parts, but "a/ /b" has a component " " that trims to empty), or a segment with control characters.

Common situations: Agent-generated paths containing glob characters like *.log; Windows drive-letter prefixes ("C:\\Users" → component "C:"); base64 or binary junk with control bytes; paths built by naive string concatenation producing '..' segments.

Related errors


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