danny-avila/LibreChat · error · Error
User principal not found
Error message
User principal not found
What it means
ensureLocalUserPrincipalExists() in PermissionService.js:38 throws when db.findUser({_id: principalId}) returns null — i.e. the principalId passed for a USER principal does not resolve to an existing local user. This is the existence check that prevents ACL entries from referencing phantom users.
Source
Thrown at api/server/services/PermissionService.js:38
/** @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();
};
/**
* @import { TPrincipal } from 'librechat-data-provider'
*/
/**
* Grant a permission to a principal for a resource using a role
* @param {Object} params - Parameters for granting role-based permissionView on GitHub (pinned to 5ff282f900)
Solutions
- Verify the principalId corresponds to a currently existing user in the target environment.
- If the user was deleted, cancel the share/grant operation rather than retrying.
- In multi-tenant setups, confirm the principalId belongs to the same tenant before granting.
Defensive patterns
Strategy: validation
Validate before calling
async function assertUserExists(principalId) {
const u = await db.findUser({ _id: principalId }, '_id');
if (!u) throw new Error(`no user for ${principalId}`);
} Prevention
- Look up the user immediately before granting, since a stale id may have been deleted.
- In multi-tenant deployments, scope the lookup by tenantId.
When it happens
Trigger: grantPermission (or a sibling ACL call) is invoked with principalType=USER and a principalId that is a valid ObjectId shape but does not exist in the users collection. Common right after a user was deleted, or when an id is transcribed from another tenant/environment.
Common situations: Cross-environment copy of an agent share that references a user id not present locally. A user was soft/hard-deleted but still referenced in a pending share operation. Multi-tenant leak where a principalId from tenant A is used in tenant B.
Related errors
- Invalid resourceType: ${resourceType}. Valid types: ${validT
- Group principal not found
- Invalid principal type: ${principalType}
- 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/8406077033ef1bf3.
Report an issue: GitHub.