{"record":{"id":"f0c9eb74de329648","repo":"semaphoreui/semaphore","slug":"invalid-project-or-environment-id","errorCode":null,"errorMessage":"invalid project or environment ID","messagePattern":"invalid project or environment ID","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/server/environment_svc.go","lineNumber":33,"sourceCode":"\tencryptionService AccessKeyEncryptionService,\n\tsecretStorageRepo db.SecretStorageRepository,\n) EnvironmentService {\n\treturn &EnvironmentServiceImpl{\n\t\tenvironmentRepo:   environmentRepo,\n\t\tencryptionService: encryptionService,\n\t\tsecretStorageRepo: secretStorageRepo,\n\t}\n}\n\ntype EnvironmentServiceImpl struct {\n\tenvironmentRepo   db.EnvironmentManager\n\tencryptionService AccessKeyEncryptionService\n\tsecretStorageRepo db.SecretStorageRepository\n}\n\nfunc (s *EnvironmentServiceImpl) Delete(projectID int, environmentID int) (err error) {\n\tif projectID <= 0 || environmentID <= 0 {\n\t\treturn fmt.Errorf(\"invalid project or environment ID\")\n\t}\n\n\tenv, err := s.environmentRepo.GetEnvironment(projectID, environmentID)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tsecrets, err := s.environmentRepo.GetEnvironmentSecrets(projectID, environmentID)\n\tif err != nil {\n\t\treturn\n\t}\n\n\terr = s.environmentRepo.DeleteEnvironment(projectID, environmentID)\n\n\tif err != nil {\n\t\treturn\n\t}\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/services/server/environment_svc.go#L15-L51","documentation":"EnvironmentServiceImpl.Delete validates its identifiers up front: projectID and environmentID must both be positive integers. Passing zero, negative values, or unset IDs is rejected immediately with this error before any repository or secret-storage work happens.","triggerScenarios":"Calling Delete with projectID <= 0 or environmentID <= 0 — typically uninitialized variables, default-zero structs, or a caller that failed to parse IDs from request input.","commonSituations":"HTTP handlers not validating/parsing query or path parameters; Go zero values from partially populated request structs; tests or scripts passing placeholder IDs.","solutions":["Validate that both projectID and environmentID are > 0 before calling Delete.","Fix upstream parsing (strconv.Atoi errors ignored, missing path params) so real IDs reach the call.","Return a 400-level error to the client when IDs are absent instead of invoking Delete with zero values."],"exampleFix":"// before\nsvc.Delete(0, envID)\n// after\nif projectID > 0 && environmentID > 0 {\n    err := svc.Delete(projectID, environmentID)\n}","handlingStrategy":"validation","validationCode":"if projectID <= 0 || environmentID <= 0 {\n    return errors.New(\"project and environment IDs must be positive integers\")\n}","typeGuard":null,"tryCatchPattern":"if err := envSvc.Delete(projectID, environmentID); err != nil && strings.Contains(err.Error(), \"invalid project or environment ID\") { /* fix ID parsing upstream */ }","preventionTips":["Check strconv/parameter parsing errors before using parsed IDs.","Reject requests with missing/zero IDs at the handler layer with a 400 response.","Avoid relying on zero-value struct fields as identifiers."],"tags":["go","validation","identifiers"],"backgroundTag":"invalid-argument-value","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"}