{"record":{"id":"90489de596886d02","repo":"lima-vm/lima","slug":"cannot-convert-q-to-an-msys-style-path-input-is","errorCode":null,"errorMessage":"cannot convert %#q to an MSYS-style path: input is not an absolute drive-letter path","messagePattern":"cannot convert %#q to an MSYS-style path: input is not an absolute drive-letter path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/fsutil/fsutil_windows.go","lineNumber":53,"sourceCode":"\t\treturn strings.TrimSpace(string(out)), nil\n\t}\n\tif !errors.Is(err, exec.ErrNotFound) && !errors.Is(err, fs.ErrNotExist) {\n\t\treturn \"\", fmt.Errorf(\"failed to run %#q on %#q: %#q: %w\", cygpathExe, orig, strings.TrimSpace(string(out)), err)\n\t}\n\n\tlogrus.WithError(err).Debugf(\"%#q not found for %#q, attempting native conversion\", cygpathExe, orig)\n\n\treturn windowsSubsystemPathWithoutCygpath(orig)\n}\n\nfunc windowsSubsystemPathWithoutCygpath(orig string) (string, error) {\n\t// The /c/... form this produces is the MSYS2 and Git-for-Windows\n\t// convention; stock Cygwin defaults to /cygdrive/c/. Only an absolute\n\t// drive-letter path (\"C:\\foo\") has a well-defined form here. A\n\t// drive-relative path (\"C:foo\") would become an unrelated absolute\n\t// path, so reject it.\n\tif !filepath.IsAbs(orig) {\n\t\treturn \"\", fmt.Errorf(\"cannot convert %#q to an MSYS-style path: input is not an absolute drive-letter path\", orig)\n\t}\n\n\t// UNC path (\"\\\\server\\share\\foo\") is rejected here.\n\tif vol := filepath.VolumeName(orig); len(vol) == 2 && vol[1] == ':' {\n\t\t// orig[2:] starts with a separator for an absolute drive path\n\t\t// (C:\\foo, C:/foo); strip it so the result stays canonical.\n\t\ttail := strings.TrimPrefix(filepath.ToSlash(orig[2:]), \"/\")\n\t\tconverted := \"/\" + strings.ToLower(vol[:1]) + \"/\" + tail\n\t\tlogrus.Debugf(\"native cygpath fallback: %#q -> %#q\", orig, converted)\n\t\treturn converted, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"cannot convert %#q to an MSYS-style path: input is not an absolute drive-letter path\", orig)\n}\n\n// WindowsSubsystemPathForLinux converts a Windows path to the WSL form of\n// the given distro (e.g. C:\\Users\\jan -> /mnt/c/Users/jan) via wsl.exe.\nfunc WindowsSubsystemPathForLinux(ctx context.Context, orig, distro string) (string, error) {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/fsutil/fsutil_windows.go#L35-L71","documentation":"The native cygpath fallback only has a well-defined MSYS-style mapping for absolute drive-letter paths (\"C:\\foo\" -> \"/c/foo\"). If the input path is not absolute (relative path or drive-relative like \"C:foo\"), conversion would silently produce an unrelated absolute path, so the function rejects it with this error.","triggerScenarios":"Calling WindowsSubsystemPath (fallback path, i.e. cygpath.exe missing) with a relative path like \"foo\\bar\", or a drive-relative path like \"C:foo\\bar\" on Windows.","commonSituations":"Passing a path built from a relative working directory or user-supplied relative input; deriving paths from tools that return drive-relative results; misusing the API which expects fully-qualified Windows paths.","solutions":["Convert the input to an absolute path before calling: filepath.Abs(orig) resolved against the intended working directory.","Ensure the path starts with a drive letter followed by a separator (C:\\...).","Reject or prompt for absolute paths at the application's input boundary.","Prefer installing cygpath (Git for Windows) so the primary conversion path handles more cases — though absoluteness is still required by the fallback."],"exampleFix":"// before\np, err := fsutil.WindowsSubsystemPath(ctx, relPath)\n// after\nabs, err := filepath.Abs(relPath)\nif err != nil { return err }\np, err := fsutil.WindowsSubsystemPath(ctx, abs)","handlingStrategy":"validation","validationCode":"abs, err := filepath.Abs(orig)\nif err != nil { return err }\nif vol := filepath.VolumeName(abs); len(vol) != 2 || vol[1] != ':' {\n    return fmt.Errorf(\"need an absolute drive-letter path, got %q\", orig)\n}\norig = abs","typeGuard":"func isAbsoluteDriveLetterPath(p string) bool {\n    vol := filepath.VolumeName(p)\n    return len(vol) == 2 && vol[1] == ':' && len(p) > 2 && (p[2] == '\\\\' || p[2] == '/')\n}","tryCatchPattern":"p, err := fsutil.WindowsSubsystemPath(ctx, orig)\nif err != nil && strings.Contains(err.Error(), \"not an absolute drive-letter path\") {\n    return fmt.Errorf(\"%q must be an absolute path like C:\\\\foo; resolve it against the working directory first\", orig)\n}","preventionTips":["Always filepath.Abs() user-supplied relative paths before conversion","Reject drive-relative paths (C:foo) at input validation","Document that the API requires fully-qualified Windows paths"],"tags":["windows","fsutil","path-conversion","validation"],"backgroundTag":"invalid-path-format","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}