{"record":{"id":"2a1c06269baeccb0","repo":"docker/cli","slug":"releases-is-a-reserved-keyword-and-cannot-be-remov","errorCode":null,"errorMessage":"releases is a reserved keyword and cannot be removed","messagePattern":"releases is a reserved keyword and cannot be removed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/docker-trust/trust/signer_remove.go","lineNumber":101,"sourceCode":"\t\t\t\"Are you sure you want to continue?\",\n\t\t\tsignerName, repoName, repoName,\n\t\t)\n\t\treturn prompt.Confirm(ctx, dockerCLI.In(), dockerCLI.Out(), message)\n\t}\n\treturn false, nil\n}\n\n// removeSingleSigner attempts to remove a single signer and returns whether signer removal happened.\n// The signer not being removed doesn't necessarily raise an error e.g. user choosing \"No\" when prompted for confirmation.\nfunc removeSingleSigner(ctx context.Context, dockerCLI command.Cli, repoName, signerName string, forceYes bool) (bool, error) {\n\timgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, authResolver(dockerCLI), repoName)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tsignerDelegation := data.RoleName(\"targets/\" + signerName)\n\tif signerDelegation == releasesRoleTUFName {\n\t\treturn false, errors.New(\"releases is a reserved keyword and cannot be removed\")\n\t}\n\tnotaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull)\n\tif err != nil {\n\t\treturn false, trust.NotaryError(imgRefAndAuth.Reference().Name(), err)\n\t}\n\tdelegationRoles, err := notaryRepo.GetDelegationRoles()\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"error retrieving signers for %s: %w\", repoName, err)\n\t}\n\tvar role data.Role\n\tfor _, delRole := range delegationRoles {\n\t\tif delRole.Name == signerDelegation {\n\t\t\trole = delRole\n\t\t\tbreak\n\t\t}\n\t}\n\tif role.Name == \"\" {\n\t\treturn false, fmt.Errorf(\"no signer %s for repository %s\", signerName, repoName)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cmd/docker-trust/trust/signer_remove.go#L83-L119","documentation":"Returned by removeSingleSigner when the signer delegation name ('targets/' + signerName) equals the reserved releasesRoleTUFName ('targets/releases'). The releases role is system-managed and cannot be removed through the signer-remove command; removing it would destroy the release-signing delegation.","triggerScenarios":"Running 'docker trust signer remove releases <repo>' — the guard at signer_remove.go:100 rejects it immediately.","commonSituations":"Trying to clean up the releases role like any other signer; scripting removal of all signers including the reserved one; misunderstanding that releases is special.","solutions":["Remove only real user-defined signers, not 'releases'.","If you need to alter the releases delegation keys, use the appropriate notary low-level commands or re-sign to republish it.","List actual signers with 'docker trust inspect --pretty <repo>' and exclude 'releases' from removal."],"exampleFix":"# before: docker trust signer remove releases myrepo\n# after:  docker trust signer remove alice myrepo   # remove a real signer instead","handlingStrategy":"validation","validationCode":"// Reject attempts to remove the reserved releases role\nfunc validateRemovableSigner(name string) error {\n\tif data.RoleName(\"targets/\"+name) == releasesRoleTUFName {\n\t\treturn errors.New(\"releases is a reserved keyword and cannot be removed\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never attempt to remove the 'releases' signer; it is reserved.","Filter 'releases' out of batch signer-removal scripts.","Use docker trust inspect to enumerate real (removable) signers."],"tags":["trust","notary","signer","reserved-keyword","releases"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}