{"record":{"id":"d0528f9c219100d8","repo":"larksuite/cli","slug":"path-must-not-address-an-ntfs-alternate-data-strea","errorCode":null,"errorMessage":"path must not address an NTFS alternate data stream","messagePattern":"path must not address an NTFS alternate data stream","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/vfs/localfileio/path_local_windows.go","lineNumber":32,"sourceCode":"// validatePathPlatform rejects Windows path shapes the policy cannot reason\n// about: network/device namespaces (UNC, \\\\?\\) and NTFS alternate data\n// streams (a colon anywhere past the drive letter would address a hidden\n// stream on an otherwise-allowed file).\nfunc validatePathPlatform(path string) error {\n\tif isWindowsNonLocalNamespace(path) {\n\t\treturn fmt.Errorf(\"path must not use a Windows network or device namespace\")\n\t}\n\tcleaned := filepath.Clean(path)\n\t// A drive-relative path (\"C:foo\") carries a volume but is not absolute: it\n\t// resolves against that drive's own current directory, so the location it\n\t// names is not the one this validation can see. It is also how the stream\n\t// check below would be slipped, since \"C:\" is stripped as the volume and\n\t// the remaining \"foo\" holds no colon.\n\tif filepath.VolumeName(cleaned) != \"\" && !filepath.IsAbs(cleaned) {\n\t\treturn fmt.Errorf(\"path must not be drive-relative; give a full path or a path without a drive letter\")\n\t}\n\tif strings.Contains(cleaned[len(filepath.VolumeName(cleaned)):], \":\") {\n\t\treturn fmt.Errorf(\"path must not address an NTFS alternate data stream\")\n\t}\n\treturn nil\n}\n\nfunc validateLocalInputPlatform(path string) error {\n\tif isWindowsNonLocalNamespace(path) {\n\t\treturn fmt.Errorf(\"local input path must not use a Windows network or device namespace\")\n\t}\n\n\tcleaned := filepath.Clean(path)\n\tvolume := filepath.VolumeName(cleaned)\n\tremainder := strings.TrimLeft(cleaned[len(volume):], `\\/`)\n\tfor _, component := range strings.FieldsFunc(remainder, func(r rune) bool {\n\t\treturn r == '\\\\' || r == '/'\n\t}) {\n\t\tif component == \".\" || component == \"..\" {\n\t\t\tcontinue\n\t\t}","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/vfs/localfileio/path_local_windows.go#L14-L50","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nf, _ := runtime.FileIO().Open(`C:\\tmp\\report.docx:Zone.Identifier`)\n// after\nf, _ := runtime.FileIO().Open(`C:\\tmp\\report.docx`)","handlingStrategy":"validation","validationCode":"func hasNTFSStream(p string) bool {\n\tp := filepath.Clean(p)\n\treturn strings.Contains(strings.TrimPrefix(p, filepath.VolumeName(p)), \":\")\n}\n// call validatePathPlatform-equivalent or reject before the API","typeGuard":"func isPlainWindowsPath(p string) bool {\n\treturn !strings.ContainsAny(strings.TrimPrefix(p, filepath.VolumeName(p)), \":\")\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["windows","filesystem","path-validation"],"backgroundTag":"ntfs-alternate-data-stream-path","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}