{"record":{"id":"ff8f4b4c6edc3cf9","repo":"hasura/graphql-engine","slug":"can-t-create-symbolic-link-source-binary-q-can","errorCode":null,"errorMessage":"can't create symbolic link, source binary (%q) cannot be found in extracted archive: %w","messagePattern":"can't create symbolic link, source binary \\(%q\\) cannot be found in extracted archive: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/plugins/util.go","lineNumber":190,"sourceCode":"\tgoos := runtime.GOOS\n\n\treturn goos == \"windows\"\n}\n\nfunc createOrUpdateLink(binDir, binary, plugin string) error {\n\tvar op errors.Op = \"plugins.createOrUpdateLink\"\n\n\tdst := filepath.Join(binDir, PluginNameToBin(plugin, IsWindows()))\n\n\terr := removeLink(dst)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"failed to remove old symlink: %w\", err))\n\t}\n\n\tif _, err := os.Stat(binary); stderrors.Is(err, fs.ErrNotExist) {\n\t\treturn errors.E(\n\t\t\top,\n\t\t\tfmt.Errorf(\n\t\t\t\t\"can't create symbolic link, source binary (%q) cannot be found in extracted archive: %w\",\n\t\t\t\tbinary,\n\t\t\t\terr,\n\t\t\t),\n\t\t)\n\t}\n\n\t// Create new\n\terr = os.Symlink(binary, dst)\n\tif err != nil {\n\t\tif IsWindows() {\n\t\t\t// If cloning the symlink fails on Windows because the user\n\t\t\t// does not have the required privileges, ignore the error and\n\t\t\t// fall back to copying the file contents.\n\t\t\t//\n\t\t\t// ERROR_PRIVILEGE_NOT_HELD is 1314 (0x522):\n\t\t\t// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx\n\t\t\tvar lerr *os.LinkError","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/plugins/util.go#L172-L208","documentation":"After clearing the old symlink, createOrUpdateLink stats the extracted binary path to confirm it exists. If os.Stat returns fs.ErrNotExist, the manifest's bin path does not point at a file inside the extracted archive, and linking is aborted with this error naming the missing binary path.","triggerScenarios":"installPlugin where the platform manifest's \"bin\" value (e.g. \"bin/mytool\") does not match any file in the extracted archive — wrong relative path, different binary name in the release, or the archive has a top-level directory the path omits.","commonSituations":"Release archives renamed the binary (myplugin-v2.0-linux-amd64 vs myplugin); manifest bin path missing the archive's top-level folder; .exe suffix issues on windows platforms entries.","solutions":["Download and extract the archive manually and note the real binary path relative to the extraction root.","Update the platform's \"bin\" field to that exact path (include the .exe suffix for windows platforms).","Reinstall; the link will then be recreated against the correct binary."],"exampleFix":"// before\n\"bin\": \"myplugin\"        // archive actually extracts to bin/myplugin\n\n// after\n\"bin\": \"bin/myplugin\"","handlingStrategy":"validation","validationCode":"want := filepath.Join(extractDir, filepath.FromSlash(pl.Bin))\nif _, err := os.Stat(want); os.IsNotExist(err) {\n\treturn fmt.Errorf(\"manifest bin %q not present after extract; listing: %v\", pl.Bin, listArchiveEntries())\n}","typeGuard":null,"tryCatchPattern":"if err := plugins.Install(...); err != nil {\n\tif strings.Contains(err.Error(), \"cannot be found in extracted archive\") {\n\t\t// extract manually, locate the real binary, fix manifest \"bin\", reinstall\n\t}\n}","preventionTips":["Keep release archive layout stable across versions; use a consistent top-level dir.","Include the .exe suffix in bin for windows platform entries.","Verify bin paths against the packaged archive in the release CI."],"tags":["plugins","install","archive","binary-path"],"backgroundTag":"missing-file-in-archive","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}