{"record":{"id":"dc1e016e47b08267","repo":"danny-avila/LibreChat","slug":"invalid-resourcetype-resourcetype-valid-types-dc1e01","errorCode":null,"errorMessage":"Invalid resourceType: ${resourceType}. Valid types: ${validTypes.join(', ')}","messagePattern":"Invalid resourceType: (.+?)\\. Valid types: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/api/src/acl/accessControlService.ts","lineNumber":426,"sourceCode":"        PermissionBits.VIEW,\n      );\n    } catch (error) {\n      if (error instanceof Error) {\n        logger.error(`[PermissionService.hasPublicAccess] Error: ${error.message}`);\n      }\n      return false;\n    }\n  }\n\n  /**\n   * Validates that the resourceType is one of the supported enum values\n   * @param {string} resourceType - The resource type to validate\n   * @throws {Error} If resourceType is not valid\n   */\n  private validateResourceType(resourceType: ResourceType): void {\n    const validTypes = Object.values(ResourceType);\n    if (!validTypes.includes(resourceType)) {\n      throw new Error(\n        `Invalid resourceType: ${resourceType}. Valid types: ${validTypes.join(', ')}`,\n      );\n    }\n  }\n}\n","sourceCodeStart":408,"sourceCodeEnd":432,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/packages/api/src/acl/accessControlService.ts#L408-L432","documentation":"validateResourceType is the central guard called by almost every public method. It rejects resourceType values that are not part of the ResourceType enum (e.g. 'agent', 'prompt'). The valid set is enumerated in the message so callers can self-correct.","triggerScenarios":"Passing a resourceType that is not a ResourceType member: a typo ('a gent'), a plural ('agents'), a custom string, undefined, or a stale literal after librechat-data-provider renamed enum members.","commonSituations":"A new resource kind added without extending the enum; a downgrade/upgrade that changed enum casing; an external integration sending its own resource vocabulary.","solutions":["Always pass a value imported from ResourceType, never a string literal.","After upgrading librechat-data-provider, diff ResourceType and update call sites.","Surfaces in nearly every ACL method — fix it once at the call site, not per method."],"exampleFix":"// before\nawait svc.checkPermission({ ..., resourceType: 'agents' });\n\n// after\nimport { ResourceType } from 'librechat-data-provider';\nawait svc.checkPermission({ ..., resourceType: ResourceType.AGENT });","handlingStrategy":"validation","validationCode":"import { ResourceType } from 'librechat-data-provider';\nconst validResourceTypes = new Set(Object.values(ResourceType));\nfunction assertResourceType(v: unknown): ResourceType {\n  if (typeof v !== 'string' || !validResourceTypes.has(v as ResourceType)) {\n    throw new Error(`Invalid resourceType: ${String(v)}`);\n  }\n  return v as ResourceType;\n}","typeGuard":"import { ResourceType } from 'librechat-data-provider';\nconst isResourceType = (v: unknown): v is ResourceType =>\n  typeof v === 'string' && Object.values(ResourceType).includes(v as ResourceType);","tryCatchPattern":null,"preventionTips":["Always reference ResourceType members; never inline literals.","After upgrading librechat-data-provider, diff ResourceType and update call sites.","Validate once at the API boundary since this guard fronts every ACL method."],"tags":["acl","validation","permissions","resource-type","enum"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}