{"record":{"id":"acb5c11505fb9639","repo":"hcengineering/platform","slug":"current-user-is-not-allowed-to-create-trainings","errorCode":null,"errorMessage":"Current user is not allowed to create trainings","messagePattern":"Current user is not allowed to create trainings","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/training-resources/src/utils/createTraining.ts","lineNumber":21,"sourceCode":"//\n\nimport { type Training, trainingPrefix, TrainingState } from '@hcengineering/training'\nimport { type Doc, type Ref } from '@hcengineering/core'\nimport { getClient } from '@hcengineering/presentation'\nimport { navigate } from '@hcengineering/ui'\nimport training from '../plugin'\nimport { trainingRoute } from '../routing/routes/trainingRoute'\nimport { canCreateTraining } from './canCreateTraining'\nimport { getCurrentEmployeeRef } from './getCurrentEmployeeRef'\nimport { getNextTrainingSeqNumber } from './getNextTrainingSeqNumber'\n\nexport type CreateTrainingData = Required<\nOmit<Training, keyof Doc | 'code' | 'state' | 'revision' | 'owner' | 'author'>\n>\n\nexport async function createTraining (data: CreateTrainingData): Promise<Ref<Training>> {\n  if (!canCreateTraining()) {\n    throw new Error('Current user is not allowed to create trainings')\n  }\n\n  const client = getClient()\n  const currentEmployeeRef = getCurrentEmployeeRef()\n  const seqNumber = await getNextTrainingSeqNumber()\n\n  const id = await client.createDoc(training.class.Training, training.space.Trainings, {\n    ...data,\n    code: `${trainingPrefix}-${seqNumber}`,\n    state: TrainingState.Draft,\n    revision: 1,\n    owner: currentEmployeeRef,\n    author: currentEmployeeRef\n  })\n\n  navigate(trainingRoute.build({ id, tab: null }))\n\n  return id","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/training-resources/src/utils/createTraining.ts#L3-L39","documentation":"createTraining performs a permission check with canCreateTraining() before doing any work and throws if the current user lacks create permission for trainings. This is an explicit client-side authorization gate mirroring server-side security. No document is created when it fires.","triggerScenarios":"Calling createTraining(data) while logged in as a user/role (e.g. guest, read-only employee) without training-create permission.","commonSituations":"Users without the appropriate role opening the create-training UI; permission mixins not configured in the space; testing as an account with insufficient roles; permission model changes after an upgrade.","solutions":["Grant the current user's role the training creation permission (configure RolesAssignment/permission mixins).","Check canCreateTraining() in the UI before showing the create action.","Log in as a user with the correct role to verify.","Review recent permission-model changes or migrations."],"exampleFix":"// before\nawait createTraining(data)\n// after\nif (canCreateTraining()) {\n  await createTraining(data)\n} else {\n  showNoPermissionNotification()\n}","handlingStrategy":"type-guard","validationCode":"if (!canCreateTraining()) { notify('You do not have permission to create trainings'); return }","typeGuard":"function mayCreateTraining(user: Account): boolean { return canCreateTraining() }","tryCatchPattern":"try { return await createTraining(data) } catch (e) { if (e.message.includes('not allowed')) showPermissionDenied(); else throw e }","preventionTips":["Gate UI actions on canCreateTraining() before invoking","Assign proper roles to users who need training creation","Keep permission mixins configured in spaces","Cover permission checks in tests"],"tags":["permissions","authorization","training"],"backgroundTag":"insufficient-permissions","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}