larksuite/cli · error

path must not address an NTFS alternate data stream

Error message

path must not address an NTFS alternate data stream

What it means

On Windows, validatePathPlatform rejects paths containing a colon after the volume prefix, which on NTFS means an alternate data stream (e.g. file.txt:Zone.Identifier). The VFS layer only supports ordinary files/directories, not ADS, so it fails fast instead of silently reading or writing stream data.

Source

Thrown at internal/vfs/localfileio/path_local_windows.go:32

// validatePathPlatform rejects Windows path shapes the policy cannot reason
// about: network/device namespaces (UNC, \\?\) and NTFS alternate data
// streams (a colon anywhere past the drive letter would address a hidden
// stream on an otherwise-allowed file).
func validatePathPlatform(path string) error {
	if isWindowsNonLocalNamespace(path) {
		return fmt.Errorf("path must not use a Windows network or device namespace")
	}
	cleaned := filepath.Clean(path)
	// A drive-relative path ("C:foo") carries a volume but is not absolute: it
	// resolves against that drive's own current directory, so the location it
	// names is not the one this validation can see. It is also how the stream
	// check below would be slipped, since "C:" is stripped as the volume and
	// the remaining "foo" holds no colon.
	if filepath.VolumeName(cleaned) != "" && !filepath.IsAbs(cleaned) {
		return fmt.Errorf("path must not be drive-relative; give a full path or a path without a drive letter")
	}
	if strings.Contains(cleaned[len(filepath.VolumeName(cleaned)):], ":") {
		return fmt.Errorf("path must not address an NTFS alternate data stream")
	}
	return nil
}

func validateLocalInputPlatform(path string) error {
	if isWindowsNonLocalNamespace(path) {
		return fmt.Errorf("local input path must not use a Windows network or device namespace")
	}

	cleaned := filepath.Clean(path)
	volume := filepath.VolumeName(cleaned)
	remainder := strings.TrimLeft(cleaned[len(volume):], `\/`)
	for _, component := range strings.FieldsFunc(remainder, func(r rune) bool {
		return r == '\\' || r == '/'
	}) {
		if component == "." || component == ".." {
			continue
		}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Remove the :streamname suffix and address the base file path only
  2. If the goal is stream metadata (e.g. Mark-of-the-Web), read it with OS-native APIs outside the VFS layer
  3. On non-Windows hosts this check never fires; verify you are actually testing on Windows and that the path is intended

Example fix

// before
f, _ := runtime.FileIO().Open(`C:\tmp\report.docx:Zone.Identifier`)
// after
f, _ := runtime.FileIO().Open(`C:\tmp\report.docx`)
Defensive patterns

Strategy: validation

Validate before calling

func hasNTFSStream(p string) bool {
	p := filepath.Clean(p)
	return strings.Contains(strings.TrimPrefix(p, filepath.VolumeName(p)), ":")
}
// call validatePathPlatform-equivalent or reject before the API

Type guard

func isPlainWindowsPath(p string) bool {
	return !strings.ContainsAny(strings.TrimPrefix(p, filepath.VolumeName(p)), ":")
}

Prevention

When it happens

Trigger: Passing a path like C:\data\file.txt:stream or file.txt:$DATA into any FileIO operation (open/read/write/validate) on Windows, where the colon after VolumeName is stripped of the drive prefix yet remains in the remainder.

Common situations: Copy-pasting a 'Zone.Identifier' or 'Microsoft.VisualStudio.*' stream path from security tooling, shell tab-completion of ADS paths, or programmatically addressing metadata streams on downloaded files.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/d0528f9c219100d8. Report an issue: GitHub.