{"record":{"id":"bf67328eae71d28f","repo":"semaphoreui/semaphore","slug":"name-can-not-be-empty","errorCode":null,"errorMessage":"name can not be empty","messagePattern":"name can not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db/AccessKey.go","lineNumber":153,"sourceCode":"\ntype SshKey struct {\n\tLogin      string `json:\"login\"`\n\tPassphrase string `json:\"passphrase\"`\n\tPrivateKey string `json:\"private_key\"`\n}\n\ntype AccessKeyRole int\n\nconst (\n\tAccessKeyRoleAnsibleUser = iota\n\tAccessKeyRoleAnsibleBecomeUser\n\tAccessKeyRoleAnsiblePasswordVault\n\tAccessKeyRoleGit\n)\n\nfunc (key *AccessKey) Validate(validateSecretFields bool) error {\n\tif key.Name == \"\" {\n\t\treturn fmt.Errorf(\"name can not be empty\")\n\t}\n\n\t//if !validateSecretFields {\n\t//\treturn nil\n\t//}\n\n\t//switch key.Type {\n\t//case AccessKeySSH:\n\t//\tif key.SshKey.PrivateKey == \"\" {\n\t//\t\treturn fmt.Errorf(\"private key can not be empty\")\n\t//\t}\n\t//case AccessKeyLoginPassword:\n\t//\tif key.LoginPassword.Password == \"\" {\n\t//\t\treturn fmt.Errorf(\"password can not be empty\")\n\t//\t}\n\t//}\n\n\treturn nil","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/db/AccessKey.go#L135-L171","documentation":"AccessKey.Validate rejects an AccessKey whose Name field is an empty string. Every access key stored in Semaphore (SSH key, login password, Ansible password vault, Git credentials) must have a non-empty name used as its identifier in the UI and API. The check runs before saving or serializing the key's secret.","triggerScenarios":"Calling UpdateAccessKey with a request body lacking the \"name\" field, or SerializeSecret on an AccessKey object constructed with only a Secret/credentials payload and no Name.","commonSituations":"API clients POST/PUT /api/access-keys with only the key material but omit \"name\"; Terraform/Ansible automation building key JSON from variables where the name variable is unset; partial struct unmarshal after an API schema change.","solutions":["Include a non-empty \"name\" field in the access-key request payload","Trim whitespace from user-supplied names before sending; treat whitespace-only as empty and reject at the client","If building the AccessKey struct in Go, set key.Name before calling Validate/SerializeSecret"],"exampleFix":"// before\nkey := AccessKey{Type: db.AccessKeyRoleGit, Secret: secret}\n// after\nkey := AccessKey{Name: \"deploy-key\", Type: db.AccessKeyRoleGit, Secret: secret}\nif err := key.Validate(false); err != nil {\n\tlog.Fatal(err)\n}","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(key.Name) == \"\" {\n\treturn errors.New(\"access key name is required\")\n}","typeGuard":"func hasName(key db.AccessKey) bool {\n\treturn strings.TrimSpace(key.Name) != \"\"\n}","tryCatchPattern":"if err := key.Validate(false); err != nil {\n\tif strings.Contains(err.Error(), \"name can not be empty\") {\n\t\treturn fmt.Errorf(\"access key rejected: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always include the \"name\" field in access-key API payloads","Trim and require names at the client/CI layer before submission","Validate keys in Go with key.Validate(false) before UpdateAccessKey/SerializeSecret"],"tags":["go","validation","api","access-key"],"backgroundTag":"empty-required-field","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}