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
- Remove the :streamname suffix and address the base file path only
- If the goal is stream metadata (e.g. Mark-of-the-Web), read it with OS-native APIs outside the VFS layer
- 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
- Never concatenate stream suffixes like :Zone.Identifier onto paths passed to VFS APIs
- Strip ADS metadata via OS tooling (e.g. Unblock-File in PowerShell) before handing files to the CLI
- Test path handling on Windows specifically; colon checks do not fire on Unix
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
- not a regular file (directories, devices, FIFOs, and sockets
- %s: path must be absolute, got %q
- %s: cannot stat %q: %w
- %s: path %q is a directory, not a file
- %s: path %q is a symlink (not allowed)
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/d0528f9c219100d8.
Report an issue: GitHub.