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

  1. Pass a PermissionBits value (e.g. PermissionBits.VIEW).
  2. Default to PermissionBits.VIEW when the caller has no explicit requirement.
  3. 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

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


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/cc807efaf982081e. Report an issue: GitHub.