{"record":{"id":"0799ac8969a4d9dd","repo":"kovidgoyal/kitty","slug":"failed-to-resolve-symlinks-in-v-with-error-w","errorCode":null,"errorMessage":"Failed to resolve symlinks in %#v with error: %w","messagePattern":"Failed to resolve symlinks in %#v with error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/ssh/config.go","lineNumber":248,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlocations = append(locations, locs...)\n\t}\n\tif len(locations) == 0 {\n\t\treturn nil, fmt.Errorf(\"No files to copy specified\")\n\t}\n\tif len(locations) > 1 && opts.Dest != \"\" {\n\t\treturn nil, fmt.Errorf(\"Specifying a remote location with more than one file is not supported\")\n\t}\n\thome := paths_ctx.HomePath()\n\tans = make([]*CopyInstruction, 0, len(locations))\n\tfor _, loc := range locations {\n\t\tci := CopyInstruction{local_path: loc, exclude_patterns: opts.Exclude}\n\t\tif opts.SymlinkStrategy != \"preserve\" {\n\t\t\tci.local_path, err = filepath.EvalSymlinks(loc)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"Failed to resolve symlinks in %#v with error: %w\", loc, err)\n\t\t\t}\n\t\t}\n\t\tif opts.SymlinkStrategy == \"resolve\" {\n\t\t\tci.arcname = get_arcname(ci.local_path, opts.Dest, home)\n\t\t} else {\n\t\t\tci.arcname = get_arcname(loc, opts.Dest, home)\n\t\t}\n\t\tans = append(ans, &ci)\n\t}\n\treturn\n}\n\ntype file_unique_id struct {\n\tdev, inode uint64\n}\n\nfunc excluded(pattern, path string) bool {\n\tif !strings.ContainsRune(pattern, '/') {","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/ssh/config.go#L230-L266","documentation":"Raised when filepath.EvalSymlinks fails on a copy source while the symlink strategy is not 'preserve'. The kitten tries to canonicalize the path (resolve symlink chains) before archiving, and the underlying OS call returned an error such as ENOENT or ELOOP.","triggerScenarios":"ParseCopyInstruction with symlink strategy 'resolve' (default) on a path that is a dangling symlink, a symlink loop, or a path whose target was removed between globbing and resolution.","commonSituations":"Copying from directories containing broken editor backup links or /tmp symlinks to deleted files; race with a cleanup job deleting the target; symlink loops in dotfiles repos.","solutions":["Inspect the path: readlink -f <path> to see where it fails","Remove or fix the dangling/looping symlink","Set symlink strategy to 'preserve' if you want such symlinks passed through unchanged"],"exampleFix":"# before (default resolves symlinks)\nkitty +kitten ssh --copy \"~/.some/link\" user@host\n# after\nkitty +kitten ssh --symlink-strategy preserve --copy \"~/.some/link\" user@host","handlingStrategy":"validation","validationCode":"if _, err := filepath.EvalSymlinks(path); err != nil {\n    // broken link: skip or use symlink_strategy=preserve\n}","typeGuard":null,"tryCatchPattern":"if _, err := os.Readlink(path); err == nil {\n    if _, terr := filepath.EvalSymlinks(path); terr != nil {\n        // pass through with preserve strategy instead\n    }\n}","preventionTips":["Prune dangling symlinks from copy trees (find . -xtype l)","Use symlink strategy 'preserve' when the tree intentionally contains links"],"tags":["ssh-kitten","symlink","filesystem"],"backgroundTag":"dangling-symlink-resolution","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}