vxcontrol/pentagi · error

path exceeds maximum allowed length of %d characters

Error message

path exceeds maximum allowed length of %d characters

What it means

SanitizeResourcePath (resources.go:142) enforces MaxPathLength (4096 characters) on the trimmed input. The error 'path exceeds maximum allowed length of %d characters' means the supplied path is longer than 4096 chars and is rejected before normalization to keep constructed filesystem paths within OS limits and bounded memory use.

Source

Thrown at backend/pkg/resources/resources.go:142

		return fmt.Errorf("failed to delete blob %s: %w", hash, err)
	}
	return nil
}

// SanitizeResourcePath normalises a client-supplied virtual path and ensures it
// is safe to use:
//   - trims whitespace
//   - converts backslashes to forward slashes
//   - cleans the path (removes .., double slashes, etc.)
//   - rejects absolute paths, dot-only components, and paths that exceed MaxPathLength
//   - returns an error for the empty path
func SanitizeResourcePath(p string) (string, error) {
	trimmed := strings.TrimSpace(p)
	if trimmed == "" {
		return "", fmt.Errorf("path must not be empty")
	}
	if len(trimmed) > MaxPathLength {
		return "", fmt.Errorf("path exceeds maximum allowed length of %d characters", MaxPathLength)
	}

	normalized := strings.ReplaceAll(trimmed, "\\", "/")
	if strings.HasPrefix(normalized, "/") {
		return "", fmt.Errorf("path must be relative")
	}
	for _, part := range strings.Split(normalized, "/") {
		if part == ".." {
			return "", fmt.Errorf("path must not contain parent directory traversal")
		}
	}
	cleaned := path.Clean("/" + normalized)
	// Remove the leading "/" we added for Clean, making the path relative.
	rel := strings.TrimPrefix(cleaned, "/")
	if rel == "" || rel == "." {
		return "", fmt.Errorf("invalid path")
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Truncate or shorten the path (e.g., cap the basename, hash long segments) before calling the API
  2. Flatten deep directory structures instead of mirroring long original hierarchies
  3. Sanitize the value at ingestion time (reject or shorten in the API handler) so bad paths never get stored
  4. If a stored path is already too long, migrate it to a shorter generated name and update references

Example fix

// before
sanitized, err := resources.SanitizeResourcePath(longPath) // len > 4096
// after
if len(strings.TrimSpace(longPath)) > resources.MaxPathLength {
    longPath = filepath.Join(filepath.Dir(longPath)[:64], hashedName(longPath))
}
sanitized, err := resources.SanitizeResourcePath(longPath)
Defensive patterns

Strategy: validation

Validate before calling

func pathFitsLimit(p string) bool { return len(strings.TrimSpace(p)) <= resources.MaxPathLength }

Type guard

func isAcceptablePath(p string) bool {
    t := strings.TrimSpace(p)
    return t != "" && len(t) <= resources.MaxPathLength && !strings.HasPrefix(strings.ReplaceAll(t, "\\", "/"), "/")
}

Try / catch

sanitized, err := resources.SanitizeResourcePath(p)
if err != nil {
    var maxLen = resources.MaxPathLength
    if strings.Contains(err.Error(), fmt.Sprintf("maximum allowed length of %d", maxLen)) {
        p = shortenPath(p, maxLen)
        sanitized, err = resources.SanitizeResourcePath(p)
    }
    if err != nil { return err }
}

Prevention

When it happens

Trigger: Passing paths longer than 4096 characters to SanitizeResourcePath via Resources, ZipResources, AddResourceFromFlow, or collectAndSanitizeResourcePaths — typically deeply nested or generated names, long upload filenames, or attacker-crafted oversized inputs.

Common situations: Bulk imports preserving full original directory trees; generated resource names from concatenated flow/agent IDs; malicious oversized path payloads from untrusted clients; exporting (ZipResources) a resource whose stored path grew beyond the limit.

Related errors


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