sqshq/piggymetrics · error · IllegalArgumentException

user already exists: + it.getUsername()

Error message

user already exists: + it.getUsername()

What it means

UserServiceImpl.create() checks UserRepository for an existing user with the same username before saving. If repository.findById(user.getUsername()) returns a present Optional, it throws IllegalArgumentException with the conflicting username. This is an application-level uniqueness guard for the user entity's primary key, thrown before any password hashing or persistence occurs.

Solutions

  1. Check existence before creating: if (repository.findById(user.getUsername()).isPresent()) { handle already-registered path (return, or surface a friendly 'username taken' response) }
  2. Catch IllegalArgumentException around the create() call and map it to an HTTP 409 Conflict response instead of a 500.
  3. If the user should be upserted, replace the guard with repository.save(user) directly (or findById(...).map(update).orElseGet(create)).
  4. Ensure callers use idempotency keys or check the account-service side so retried registrations don't re-enter create().

Example fix

// before
Optional<User> existing = repository.findById(user.getUsername());
existing.ifPresent(it -> { throw new IllegalArgumentException("user already exists: " + it.getUsername()); });

// after
if (repository.findById(user.getUsername()).isPresent()) {
    throw new UserExistsException(user.getUsername()); // map to 409 Conflict in the controller/@ControllerAdvice
}
// or, for idempotent upsert semantics:
// repository.save(user);
Defensive patterns

Strategy: try-catch

Validate before calling

// caller-side pre-check before invoking create()
if (userRepository.findById(user.getUsername()).isPresent()) {
    // username already taken — return 409 Conflict or merge instead of creating
    return;
}

Type guard

// Java: Optional-based narrowing
Optional<User> existing = repository.findById(user.getUsername());
if (existing.isPresent()) {
    User conflict = existing.get(); // safely narrowed, no exception path
    return;
}

Try / catch

try {
    userService.create(user);
} catch (IllegalArgumentException e) {
    // duplicate username
    return ResponseEntity.status(HttpStatus.CONFLICT).body("username already exists");
}

Prevention

When it happens

Trigger: Calling create(User) with a user whose getUsername() matches a user already persisted in the repository (e.g., POST /users with a username that was previously registered, or retrying a registration request that already succeeded).

Common situations: Duplicate registration attempts from a double-clicked signup form or retried HTTP request without idempotency handling; a microservice (e.g., account-service) provisioning a user that already exists in auth-service's database; test fixtures or seed data re-run against a persistent database; missing a pre-check like repository.findById(username).isPresent() on the client side before invoking create().

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.


AI-assisted analysis of sqshq/piggymetrics@6bb2cf9ddb (2026-09-07). Data as JSON: /api/errors/2c5fd0f36864fb85. Report an issue: GitHub.

Appendix: source

Thrown at auth-service/src/main/java/com/piggymetrics/auth/service/UserServiceImpl.java:28

import org.springframework.util.Assert;

import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {

	private final Logger log = LoggerFactory.getLogger(getClass());

	private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

	@Autowired
	private UserRepository repository;

	@Override
	public void create(User user) {

		Optional<User> existing = repository.findById(user.getUsername());
		existing.ifPresent(it-> {throw new IllegalArgumentException("user already exists: " + it.getUsername());});

		String hash = encoder.encode(user.getPassword());
		user.setPassword(hash);

		repository.save(user);

		log.info("new user has been created: {}", user.getUsername());
	}
}

View on GitHub (pinned to 6bb2cf9ddb)