Zie619/n8n-workflows · error · ValueError
Username or email already exists
Error message
Username or email already exists
What it means
UserManager.create_user() raises ValueError('Username or email already exists') when its pre-check SELECT COUNT(*) on the users table finds a row with the same username OR email. SQLite has no unique constraint enforcing this, so the check is purely application-level; the FastAPI register endpoint catches the ValueError and maps it to HTTP 400 with this detail.
Source
Thrown at src/user_management.py:175
return hashlib.sha256(password.encode()).hexdigest()
def verify_password(self, password: str, hashed: str) -> bool:
"""Verify password against hash."""
return self.hash_password(password) == hashed
def create_user(self, user_data: UserCreate) -> User:
"""Create a new user."""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
try:
# Check if username or email already exists
cursor.execute(
"SELECT COUNT(*) FROM users WHERE username = ? OR email = ?",
(user_data.username, user_data.email),
)
if cursor.fetchone()[0] > 0:
raise ValueError("Username or email already exists")
password_hash = self.hash_password(user_data.password)
cursor.execute(
"""
INSERT INTO users (username, email, full_name, password_hash, role)
VALUES (?, ?, ?, ?, ?)
""",
(
user_data.username,
user_data.email,
user_data.full_name,
password_hash,
user_data.role,
),
)
user_id = cursor.lastrowidView on GitHub (pinned to 94007c1445)
Solutions
- Register with a different username and/or email — the check matches either column
- If re-running a seed script, make it idempotent: skip or update when the user already exists
- Check existence first via GET /users/{id} or an admin list before calling create
- Server-side: add UNIQUE constraints on username and email in the schema and catch sqlite3.IntegrityError to remove the race
Example fix
// before
if cursor.fetchone()[0] > 0:
raise ValueError("Username or email already exists")
// after (schema-backed, race-free)
cursor.execute("CREATE UNIQUE INDEX IF NOT EXISTS ux_users_username ON users(username)")
cursor.execute("CREATE UNIQUE INDEX IF NOT EXISTS ux_users_email ON users(email)")
try:
cursor.execute("INSERT INTO users (...) VALUES (...)")
except sqlite3.IntegrityError:
raise ValueError("Username or email already exists") Defensive patterns
Strategy: validation
Validate before calling
def ensure_unique(user_manager, username: str, email: str) -> None:
# mirrors the pre-check inside create_user to fail fast with a clear message
existing = user_manager.get_user_by_username(username)
if existing is not None:
raise ValueError(f"username {username!r} taken")
existing = user_manager.get_user_by_email(email)
if existing is not None:
raise ValueError(f"email {email!r} taken") Try / catch
try:
user = user_manager.create_user(user_data)
except ValueError as e:
if "already exists" in str(e):
user_data.username = f"{user_data.username}_{uuid4().hex[:6]}"
user = user_manager.create_user(user_data) # or surface to the user
else:
raise Prevention
- Pre-check username and email uniqueness before INSERT
- Make seeding scripts idempotent (upsert or skip-existing)
- Back the check with UNIQUE indexes to eliminate the concurrent-registration race
When it happens
Trigger: POST /auth/register with a username or email that already exists in the SQLite database (including the auto-created default 'admin'/'admin@n8n-workflows.com' account). A re-run of registration after a partial failure, or two concurrent registrations racing past the COUNT check, can also produce it (the race instead surfaces as an IntegrityError/500 if a constraint existed; here the check-then-insert is not transactional against concurrent writers).
Common situations: Scripts that re-seed users on every startup; users re-registering with a recycled email; the default admin account blocking a second 'admin'; concurrency races since SQLite connections are opened per call with no unique index backing the check.
Related errors
- Initial Vector 'data' is undefined or missing.
- Flow token is missing.
- Insufficient stock for ${$('Retrieve Issue Request Details')
- Invalid quantity Requested: ${quantityRequested}. Must be gr
- Product ID is missing
AI-assisted analysis of Zie619/n8n-workflows@94007c1445 (2026-08-15).
Data as JSON: /api/errors/80fc861d3f69794d.
Report an issue: GitHub.