semaphoreui/semaphore · error

invalid project or environment ID

Error message

invalid project or environment ID

What it means

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.

Solutions

  1. Validate that both projectID and environmentID are > 0 before calling Delete.
  2. Fix upstream parsing (strconv.Atoi errors ignored, missing path params) so real IDs reach the call.
  3. Return a 400-level error to the client when IDs are absent instead of invoking Delete with zero values.

Example fix

// before
svc.Delete(0, envID)
// after
if projectID > 0 && environmentID > 0 {
    err := svc.Delete(projectID, environmentID)
}
Defensive patterns

Strategy: validation

Validate before calling

if projectID <= 0 || environmentID <= 0 {
    return errors.New("project and environment IDs must be positive integers")
}

Try / catch

if err := envSvc.Delete(projectID, environmentID); err != nil && strings.Contains(err.Error(), "invalid project or environment ID") { /* fix ID parsing upstream */ }

Prevention

When it happens

Trigger: 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.

Common situations: HTTP handlers not validating/parsing query or path parameters; Go zero values from partially populated request structs; tests or scripts passing placeholder IDs.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/f0c9eb74de329648. Report an issue: GitHub.

Appendix: source

Thrown at services/server/environment_svc.go:33

	encryptionService AccessKeyEncryptionService,
	secretStorageRepo db.SecretStorageRepository,
) EnvironmentService {
	return &EnvironmentServiceImpl{
		environmentRepo:   environmentRepo,
		encryptionService: encryptionService,
		secretStorageRepo: secretStorageRepo,
	}
}

type EnvironmentServiceImpl struct {
	environmentRepo   db.EnvironmentManager
	encryptionService AccessKeyEncryptionService
	secretStorageRepo db.SecretStorageRepository
}

func (s *EnvironmentServiceImpl) Delete(projectID int, environmentID int) (err error) {
	if projectID <= 0 || environmentID <= 0 {
		return fmt.Errorf("invalid project or environment ID")
	}

	env, err := s.environmentRepo.GetEnvironment(projectID, environmentID)
	if err != nil {
		return
	}

	secrets, err := s.environmentRepo.GetEnvironmentSecrets(projectID, environmentID)
	if err != nil {
		return
	}

	err = s.environmentRepo.DeleteEnvironment(projectID, environmentID)

	if err != nil {
		return
	}

View on GitHub (pinned to 1774ccb71a)