danny-avila/LibreChat · error · Error
requiredPermission must be a positive number
Error message
requiredPermission must be a positive number
What it means
checkPermission (singular requiredPermission) guards the permission check the same way the plural variants do: the requested bit mask must be a positive number. The error message uses the singular form to distinguish it from the list-style methods. Note the catch block only re-throws this specific validation error; other errors return false.
Source
Thrown at packages/api/src/acl/accessControlService.ts:361
* @param {number} params.requiredPermissions - The permission bits required (e.g., 1 for VIEW, 3 for VIEW+EDIT)
* @returns {Promise<boolean>} Whether the user has the required permission bits
*/
public async checkPermission({
userId,
role,
resourceType,
resourceId,
requiredPermission,
}: {
userId: string;
role?: string | null;
resourceType: ResourceType;
resourceId: string | Types.ObjectId;
requiredPermission: number;
}): Promise<boolean> {
try {
if (typeof requiredPermission !== 'number' || requiredPermission < 1) {
throw new Error('requiredPermission must be a positive number');
}
this.validateResourceType(resourceType);
// Get all principals for the user (user + groups + public)
const principals = await this._dbMethods.getUserPrincipals({ userId, role });
if (principals.length === 0) {
return false;
}
return await this._dbMethods.hasPermission(
principals,
resourceType,
resourceId,
requiredPermission,
);
} catch (error) {View on GitHub (pinned to 5ff282f900)
Solutions
- Pass a PermissionBits value (e.g. PermissionBits.VIEW).
- Default to PermissionBits.VIEW when the caller has no explicit requirement.
- Remember other failures inside checkPermission return false (not throw) — only this validation surfaces.
Example fix
// before
const ok = await checkPermission({ userId, resourceType, resourceId, requiredPermission: 0 });
// after
import { PermissionBits } from 'librechat-data-provider';
const ok = await checkPermission({
userId,
resourceType,
resourceId,
requiredPermission: PermissionBits.VIEW,
}); Defensive patterns
Strategy: validation
Validate before calling
import { PermissionBits } from 'librechat-data-provider';
function assertPermissionMask(v: unknown): number {
if (typeof v !== 'number' || !Number.isFinite(v) || v < 1) {
throw new Error('requiredPermission must be a positive number');
}
return v;
} Type guard
const isPermissionMask = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 1;
Prevention
- Pass PermissionBits.VIEW (or a higher mask) explicitly.
- Remember checkPermission returns false (does not throw) for non-validation failures.
- Default to PermissionBits.VIEW rather than 0.
When it happens
Trigger: Calling checkPermission with requiredPermission = 0, undefined, NaN, a string, or a negative number; computing the bit from user input that produced no bits.
Common situations: A gating call that defaults requiredPermission to 0 when nothing is selected; passing the permission name instead of the bit; arithmetic that masks the value to 0.
Related errors
- requiredPermissions must be a positive number
- Invalid resourceType: ${resourceType}. Valid types: ${validT
- User principal not found
- Group principal not found
- Invalid principal type: ${principalType}
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/cc807efaf982081e.
Report an issue: GitHub.