RocketChat/Rocket.Chat · error · Meteor.Error
error-invalid-field
error-invalid-field
Error message
bio
What it means
A runtime type guard on the bio field: saveUserProfile rejects settings.bio when it is present (truthy or empty string) but not a JS string (typeof settings.bio !== 'string'). No database write happens; the check runs before the length check and Users.setBio.
Source
Thrown at apps/meteor/server/meteor-methods/users/saveUserProfile.ts:91
!(await saveUserIdentity({
_id: this.userId,
name: settings.realname,
username: settings.username,
}))
) {
throw new Meteor.Error('error-could-not-save-identity', 'Could not save user identity', {
method: 'saveUserProfile',
});
}
}
if (settings.statusType || settings.statusText != null) {
await setUserStatusMethod(user, settings.statusType as UserStatus, settings.statusText);
}
if (user && (settings.bio || settings.bio === '')) {
if (typeof settings.bio !== 'string') {
throw new Meteor.Error('error-invalid-field', 'bio', {
method: 'saveUserProfile',
});
}
if (settings.bio.length > MAX_BIO_LENGTH) {
throw new Meteor.Error('error-bio-size-exceeded', `Bio size exceeds ${MAX_BIO_LENGTH} characters`, {
method: 'saveUserProfile',
});
}
await Users.setBio(user._id, settings.bio.trim());
}
if (user && (settings.nickname || settings.nickname === '')) {
if (typeof settings.nickname !== 'string') {
throw new Meteor.Error('error-invalid-field', 'nickname', {
method: 'saveUserProfile',
});
}
if (settings.nickname.length > MAX_NICKNAME_LENGTH) {View on GitHub (pinned to b2c16d5842)
Solutions
- Cast and validate on the client before calling: ensure typeof bio === 'string'
- Type the settings payload (bio?: string) in TS clients so the compiler blocks non-string values
- Inspect the actual DDP wire payload if a stock client triggers it - some serializer upstream is corrupting the value
Example fix
// before
Meteor.call('saveUserProfile', { bio: bioInput.valueAsNumber }, customFields);
// after
Meteor.call('saveUserProfile', { bio: String(bioInput.value) }, customFields); Defensive patterns
Strategy: type-guard
Validate before calling
if ('bio' in settings && typeof settings.bio !== 'string') {
throw new TypeError('bio must be a string');
} Type guard
const isOptionalString = (v: unknown): v is string | undefined => v === undefined || typeof v === 'string';
Try / catch
catch (err) {
if (err instanceof Meteor.Error && err.error === 'error-invalid-field' && err.reason === 'bio') {
showFieldError('bio', 'Bio must be text');
}
} Prevention
- Type the settings payload (bio?: string) in TS clients
- Cast form inputs with String() at the boundary instead of trusting bound types
- Add contract tests that send malformed field types and assert client-side rejection
When it happens
Trigger: Calling saveUserProfile with bio as a number, object, or array - e.g. bio: 123, bio: { text: '...' } - typically from a custom client, integration, or a form binding that did not cast the input value.
Common situations: Number-input form fields bound without String(); bots/integrations posting untyped JSON; REST-to-DDP bridges that pass raw JSON values through.
Related errors
- error-bio-size-exceeded
- error-nickname-size-exceeded
- duplicated-account
- error-invalid-account
- error-invalid-members
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/f64b7b15a8035448.
Report an issue: GitHub.