danny-avila/LibreChat · error · Error
Invalid resource ID: ${resourceId}
Error message
Invalid resource ID: ${resourceId} What it means
grantPermission requires resourceId to be present and a valid Mongo ObjectId (Types.ObjectId.isValid). This is checked for every grant regardless of principal type, since every ACL entry must anchor to a real resource document.
Source
Thrown at packages/api/src/acl/accessControlService.ts:85
}
// Validate principalId based on type
if (principalId && principalType === PrincipalType.ROLE) {
// Role IDs are strings (role names)
if (typeof principalId !== 'string' || principalId.trim().length === 0) {
throw new Error(`Invalid role ID: ${principalId}`);
}
} else if (
principalType &&
principalType !== PrincipalType.PUBLIC &&
(!principalId || !Types.ObjectId.isValid(principalId))
) {
// User and Group IDs must be valid ObjectIds
throw new Error(`Invalid principal ID: ${principalId}`);
}
if (!resourceId || !Types.ObjectId.isValid(resourceId)) {
throw new Error(`Invalid resource ID: ${resourceId}`);
}
this.validateResourceType(resourceType as ResourceType);
// Get the role to determine permission bits
const role = await this._dbMethods.findRoleByIdentifier(accessRoleId);
if (!role) {
throw new Error(`Role ${accessRoleId} not found`);
}
// Ensure the role is for the correct resource type
if (role.resourceType !== resourceType) {
throw new Error(
`Role ${accessRoleId} is for ${role.resourceType} resources, not ${resourceType}`,
);
}
return await this._dbMethods.grantPermission(
principalType,View on GitHub (pinned to 5ff282f900)
Solutions
- Resolve the resource's _id from the database and pass its toString().
- Validate resourceId with Types.ObjectId.isValid at the route handler and return 400 on failure.
- Ensure the resource still exists before granting permissions on it.
Example fix
// before
await grantPermission({ ..., resourceId: agentSlug });
// after
import { Types } from 'mongoose';
if (!Types.ObjectId.isValid(agentSlug)) {
return res.status(400).json({ error: 'Invalid resource id' });
}
await grantPermission({ ..., resourceId: agentSlug }); Defensive patterns
Strategy: validation
Validate before calling
import { Types } from 'mongoose';
function assertResourceId(v: unknown): string {
if (typeof v !== 'string' || !Types.ObjectId.isValid(v)) {
throw new Error(`Invalid resource ID: ${String(v)}`);
}
return v;
} Type guard
import { Types } from 'mongoose';
const isResourceId = (v: unknown): v is string =>
typeof v === 'string' && Types.ObjectId.isValid(v); Prevention
- Resolve the resource _id from the database and pass its toString().
- Return 400 at the route handler for ids that fail ObjectId.isValid.
- Confirm the resource still exists before granting on it.
When it happens
Trigger: grantPermission with resourceId undefined, null, an empty string, a slug, or any non-24-hex-char value; passing the resource's name or path instead of its _id.
Common situations: Client sends a resource slug or index instead of its Mongo id; a route parameter parsed incorrectly; the resource was deleted between fetch and grant so its id reference is stale.
Related errors
- Invalid principal ID: ${principalId}
- Invalid principal ID: ${principalId}
- Invalid resourceType: ${resourceType}. Valid types: ${validT
- User principal not found
- Group principal not found
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/cd1acb211aefa556.
Report an issue: GitHub.