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
- Pass one of: agent, promptGroup, mcpServer, remoteAgent, skill, sharedLink — exactly as exported by ResourceType.
- If you need a new resource category, add it to the ResourceType enum in packages/data-provider first, then use it.
- 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
- Type the parameter as ResourceType in TS so invalid values fail to compile.
- Centralize resourceType constants in one shared module imported by both client and server.
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
- Invalid principal type: ${principalType}
- User principal not found
- Group principal not found
- Principal ID is required for user, group, and role principal
- Invalid role ID: ${principalId}
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/33445cf429908370.
Report an issue: GitHub.