larksuite/cli · error
path must not be drive-relative; give a full path or a path
Error message
path must not be drive-relative; give a full path or a path without a drive letter
What it means
On Windows, `validatePathPlatform` rejects drive-relative paths like `C:foo` — a path with a volume but no root slash. Such a path resolves against that drive's own per-drive current directory, so the validated location would differ from the one the OS opens; it would also slip past the NTFS alternate-data-stream colon check. The error is wrapped with the flag name by safePath.
Source
Thrown at internal/vfs/localfileio/path_local_windows.go:29
"strings"
)
// 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 == '/'
}) {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Insert the root separator: change `C:foo` to `C:\foo`.
- Drop the drive letter and use a normal relative path resolved against the current directory.
- Rebuild the path programmatically with filepath.Join (or filepath.Abs) instead of string concatenation.
Example fix
// before
p := "C:" + "data\\out.bin" // C:data\out.bin
// after
p := filepath.Join("C:\\", "data", "out.bin") // C:\data\out.bin Defensive patterns
Strategy: validation
Validate before calling
// Go: normalize drive-relative paths to full paths
if vol := filepath.VolumeName(p); vol != "" && !filepath.IsAbs(p) {
p = vol + "\\" + strings.TrimPrefix(p, vol)
} Prevention
- Build Windows paths with filepath.Join rather than string concatenation.
- After `cd D:` in cmd.exe, remember the prompt directory is per-drive; always pass rooted paths to scripts.
- Run filepath.Abs (or an equivalent) on user-supplied Windows paths before storing them in configs.
When it happens
Trigger: Passing `--file C:report.pdf` or `--output D:data\out.bin` on Windows (drive letter immediately followed by a non-separator). Note `C:\abs\path` and plain `relative\path` are fine.
Common situations: Scripts that string-concatenate a drive letter with a path missing the separator (`drive + ':' + path`); paths captured from tools that report drive-relative locations; per-drive working directories left over from `cd D:` in cmd.exe.
Related errors
- path must not use a Windows network or device namespace
- %s: path must be absolute, got %q
- %s: path %q is a directory, not a file
- %q has invalid relative path %q
- not a regular file (directories, devices, FIFOs, and sockets
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/f55455161cd34abb.
Report an issue: GitHub.