{"record":{"id":"90e1642613ec37aa","repo":"gravitational/teleport","slug":"version-is-linked","errorCode":null,"errorMessage":"version is linked","messagePattern":"version is linked","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/autoupdate/agent/updater.go","lineNumber":344,"sourceCode":"\tTryLinkSystem(ctx context.Context) error\n\t// Unlink unlinks the specified revision of Teleport from path.\n\t// Unlink must be idempotent.\n\tUnlink(ctx context.Context, rev Revision, pathDir string) error\n\t// UnlinkSystem unlinks the system (package) installation of Teleport from the system linking location.\n\t// UnlinkSystem must be idempotent.\n\tUnlinkSystem(ctx context.Context) error\n\t// List the installed revisions of Teleport.\n\tList(ctx context.Context) (revisions []Revision, err error)\n\t// Remove the Teleport agent at revision.\n\t// Remove must be idempotent.\n\tRemove(ctx context.Context, rev Revision) error\n\t// IsLinked returns true if the revision is linked to path.\n\tIsLinked(ctx context.Context, rev Revision, pathDir string) (bool, error)\n}\n\nvar (\n\t// ErrLinked is returned when a linked version cannot be operated on.\n\tErrLinked = errors.New(\"version is linked\")\n\t// ErrNotSupported is returned when the operation is not supported on the platform.\n\tErrNotSupported = errors.New(\"not supported on this platform\")\n\t// ErrNotAvailable is returned when the operation is not available at the current version of the platform.\n\tErrNotAvailable = errors.New(\"not available at this version\")\n\t// ErrNoBinaries is returned when no binaries are available to be linked.\n\tErrNoBinaries = errors.New(\"no binaries available to link\")\n\t// ErrFilePresent is returned when a file is present.\n\tErrFilePresent = errors.New(\"file present\")\n\t// ErrNotInstalled is returned when Teleport is not installed.\n\tErrNotInstalled = errors.New(\"not installed\")\n)\n\n// Process provides an API for interacting with a running Teleport process.\ntype Process interface {\n\t// Name of the process.\n\tName() string\n\t// Reload must reload the Teleport process as gracefully as possible.\n\t// If the process is not healthy after reloading, Reload must return an error.","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/gravitational/teleport/blob/1283425b60ec5f60d509ba4c791183d452923ff7/lib/autoupdate/agent/updater.go#L326-L362","documentation":"ErrLinked is the sentinel returned when an updater operation (remove, replace, install) attempts to modify a revision that is currently linked to a path — i.e. it is the active binary pointed at by the stable link. Deleting or replacing a linked revision would break the running installation, so the installer/updater refuse with ErrLinked wrapped with context.","triggerScenarios":"Calling Installer.Remove(ctx, rev) for a revision where IsLinked is true (updater.go:1027 returns trace.Wrap(ErrLinked, \"refusing to remove\")); or Installer.Replace targeting newname where the existing name at the target is still the linked oldname (installer.go:1075 returns trace.Wrap(ErrLinked, \"refusing to replace link at %s\", newname)).","commonSituations":"Attempting to prune old revisions while the target revision is the currently active link; re-running an install/upgrade where the link was never advanced past the old revision; manual manipulation of the versions directory that leaves a linked revision in the way of a replace.","solutions":["Check IsLinked(ctx, rev, pathDir) before removing/replacing and skip (or advance the link first) when it returns true.","Re-link to a newer revision first (complete the upgrade), then retry the remove/replace of the old revision.","If you truly want to remove the active revision, remove the stable link pointing at it before calling Remove — at your own risk.","Update to a newer Teleport version if this arises during a normal upgrade flow; link handling may have been fixed."],"exampleFix":"// before\nif err := u.Installer.Remove(ctx, rev); err != nil { return err }\n// after\nlinked, _ := u.Installer.IsLinked(ctx, rev, binDir)\nif !linked {\n    if err := u.Installer.Remove(ctx, rev); err != nil { return err }\n}","handlingStrategy":"validation","validationCode":"// Guard before mutating a revision:\nlinked, err := inst.IsLinked(ctx, rev, binDir)\nif err != nil { return err }\nif linked { return nil } // skip remove/replace","typeGuard":"func isLinkedErr(err error) bool { return errors.Is(err, agent.ErrLinked) }","tryCatchPattern":"err := u.Installer.Remove(ctx, rev)\nif errors.Is(err, agent.ErrLinked) {\n    // advance the link to a newer revision, then retry\n}","preventionTips":["Always call IsLinked before Remove or Replace.","Complete link advancement to a new revision before pruning old ones.","Avoid manually editing the versions directory or stable links."],"tags":["autoupdate","go","sentinel-error","filesystem"],"backgroundTag":"revision-already-linked","analyzedSha":"1283425b60ec5f60d509ba4c791183d452923ff7","analyzedAt":"2026-09-02T04:06:41.601Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}