danny-avila/LibreChat · error · Error

Invalid resourceType: ${resourceType}. Valid types: ${validT

Error message

Invalid resourceType: ${resourceType}. Valid types: ${validTypes.join(', ')}

What it means

validateResourceType() in PermissionService.js:31 throws when resourceType is not one of the ResourceType enum values (agent, promptGroup, mcpServer, remoteAgent, skill, sharedLink). It is the gate used by grantPermission and related ACL writers to prevent persisting permission records against an unsupported resource category.

Source

Thrown at api/server/services/PermissionService.js:31

  getUserEntraGroups,
  getEntraGroupDetailsBatch,
  getGroupMembers,
  getGroupOwners,
} = require('~/server/services/GraphApiService');
const db = require('~/models');

/** @type {boolean|null} */
let transactionSupportCache = null;

/**
 * Validates that the resourceType is one of the supported enum values
 * @param {string} resourceType - The resource type to validate
 * @throws {Error} If resourceType is not valid
 */
const validateResourceType = (resourceType) => {
  const validTypes = Object.values(ResourceType);
  if (!validTypes.includes(resourceType)) {
    throw new Error(`Invalid resourceType: ${resourceType}. Valid types: ${validTypes.join(', ')}`);
  }
};

const ensureLocalUserPrincipalExists = async (principalId) => {
  const user = await db.findUser({ _id: principalId }, '_id');
  if (!user) {
    throw new Error('User principal not found');
  }
  return user._id.toString();
};

const ensureLocalGroupPrincipalExists = async (principalId) => {
  const group = await db.findGroupById(principalId, { _id: 1 });
  if (!group) {
    throw new Error('Group principal not found');
  }
  return group._id.toString();
};

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Pass one of: agent, promptGroup, mcpServer, remoteAgent, skill, sharedLink — exactly as exported by ResourceType.
  2. If you need a new resource category, add it to the ResourceType enum in packages/data-provider first, then use it.
  3. If invoking from TypeScript, type the parameter as ResourceType so the compiler catches typos.

Example fix

// before
grantPermission({ resourceType: 'agents', ... });
// after
import { ResourceType } from 'librechat-data-provider';
grantPermission({ resourceType: ResourceType.AGENT, ... });
Defensive patterns

Strategy: type-guard

Validate before calling

const VALID_RESOURCE_TYPES = new Set(Object.values(ResourceType));
function assertResourceType(t) {
  if (!VALID_RESOURCE_TYPES.has(t)) throw new Error(`unsupported resourceType: ${t}`);
}

Type guard

const isResourceType = (t) => Object.values(ResourceType).includes(t);

Prevention

When it happens

Trigger: A caller of grantPermission/related ACL functions passes a resourceType string that is not in the ResourceType enum — e.g. a typo 'agents', a legacy value 'prompt', or a frontend-invented category. Reached after principal validation but the function is also called directly elsewhere.

Common situations: Frontend hard-coded a singular/plural form that does not match the enum. A new resource type was added to the UI but not to the ResourceType enum in data-provider. A migration left stale resourceType strings in older API callers.

Related errors


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