Mintplex-Labs/anything-llm · error
Username must be at least 2 characters
Error message
Username must be at least 2 characters
What it means
Thrown by the username validator in the User model when User.create or User.update receives a username shorter than 2 characters after String() coercion. The check runs before any Prisma write, so the whole operation is rejected as a validation failure. The validator's argument defaults to "", so explicitly sending username: "" (or undefined through create) also triggers it. Note that User.update skips username validation when the value equals the current username, so this only fires when the username is genuinely being changed to a too-short value (or on create).
Solutions
- Send a username of 2-64 characters that starts with a lowercase letter
- Add client-side validation (minlength=2 plus trim) before submitting the create/update request
- If the username is unchanged, omit the key from the update payload instead of sending an empty string
- For programmatic callers, assert String(username).length >= 2 before calling User.create/User.update
Example fix
// before
await User.create({ username: "j", password: passwordHash });
// after
await User.create({ username: "jo", password: passwordHash }); Defensive patterns
Strategy: validation
Validate before calling
function isValidUsername(username) {
const u = String(username ?? "");
return u.length >= 2 && u.length <= 64 && /^[a-z][a-z0-9._@-]*$/.test(u);
}
// before User.create / User.update
if (!isValidUsername(input.username)) {
return res.status(400).json({ error: "Username must be 2-64 chars, starting with a lowercase letter" });
} Try / catch
try {
const { user, message } = await User.create({ username, password });
} catch (e) {
if (e.message.startsWith("Username")) return res.status(400).json({ error: e.message });
throw e;
} Prevention
- Enforce minlength=2 plus trim in the client form
- Omit the username key entirely when it is not being changed; never send an empty string
- For SSO/LDAP sync, validate generated usernames against the same regex before calling create
When it happens
Trigger: Calling User.create({ username: "k" }) or user.update(userId, { username: "" }); an admin POST/PATCH to the user endpoints with an empty or single-character username; a seed script generating 1-character usernames; a form that submits the key with an empty string instead of omitting it.
Common situations: Frontend forms without minlength enforcement or trimming; SSO/LDAP provisioning that maps a 1-character attribute to username; import scripts that derive usernames from truncated email prefixes; API clients that always send every field, including empty ones.
Related errors
- Username must start with a lowercase letter and only…
- Bio cannot be longer than 1,000 characters
- Daily message limit must be null or a number greater than…
- Invalid role. Allowed roles are
- addToWorkspaces must be a string of comma-separated…
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/6942a1367a47bde5.
Report an issue: GitHub.
Appendix: source
Thrown at server/models/user.js:41
"role",
"suspended",
"dailyMessageLimit",
"bio",
],
validations: {
/**
* Unix-style username regex:
* - Must start with a lowercase letter
* - Can contain lowercase letters, digits, underscores, hyphens, @ signs, and periods
* - 2-64 characters long
*/
username: (newValue = "") => {
try {
const username = String(newValue);
if (username.length > 64)
throw new Error("Username cannot be longer than 64 characters");
if (username.length < 2)
throw new Error("Username must be at least 2 characters");
if (!User.usernameRegex.test(username))
throw new Error(
"Username must start with a lowercase letter and only contain lowercase letters, numbers, underscores, hyphens, and periods"
);
return username;
} catch (e) {
throw new Error(e.message);
}
},
role: (role = "default") => {
const VALID_ROLES = ["default", "admin", "manager"];
if (!VALID_ROLES.includes(role)) {
throw new Error(
`Invalid role. Allowed roles are: ${VALID_ROLES.join(", ")}`
);
}
return String(role);
},View on GitHub (pinned to 3aec848f28)