hasura/graphql-engine · error
can't create symbolic link, source binary (%q) cannot be fou
Error message
can't create symbolic link, source binary (%q) cannot be found in extracted archive: %w
What it means
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.
Source
Thrown at cli/plugins/util.go:190
goos := runtime.GOOS
return goos == "windows"
}
func createOrUpdateLink(binDir, binary, plugin string) error {
var op errors.Op = "plugins.createOrUpdateLink"
dst := filepath.Join(binDir, PluginNameToBin(plugin, IsWindows()))
err := removeLink(dst)
if err != nil {
return errors.E(op, fmt.Errorf("failed to remove old symlink: %w", err))
}
if _, err := os.Stat(binary); stderrors.Is(err, fs.ErrNotExist) {
return errors.E(
op,
fmt.Errorf(
"can't create symbolic link, source binary (%q) cannot be found in extracted archive: %w",
binary,
err,
),
)
}
// Create new
err = os.Symlink(binary, dst)
if err != nil {
if IsWindows() {
// If cloning the symlink fails on Windows because the user
// does not have the required privileges, ignore the error and
// fall back to copying the file contents.
//
// ERROR_PRIVILEGE_NOT_HELD is 1314 (0x522):
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx
var lerr *os.LinkErrorView on GitHub (pinned to 724551b9ae)
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.
Example fix
// before "bin": "myplugin" // archive actually extracts to bin/myplugin // after "bin": "bin/myplugin"
Defensive patterns
Strategy: validation
Validate before calling
want := filepath.Join(extractDir, filepath.FromSlash(pl.Bin))
if _, err := os.Stat(want); os.IsNotExist(err) {
return fmt.Errorf("manifest bin %q not present after extract; listing: %v", pl.Bin, listArchiveEntries())
} Try / catch
if err := plugins.Install(...); err != nil {
if strings.Contains(err.Error(), "cannot be found in extracted archive") {
// extract manually, locate the real binary, fix manifest "bin", reinstall
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- plugin %q does not offer installation for this platform
- install failed: %w
- installation receipt could not be stored, uninstall may fail
- could not create staging dir %q: %w
- failed to unpack into staging dir: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/ff8f4b4c6edc3cf9.
Report an issue: GitHub.