{"record":{"id":"d7899426ab12d96e","repo":"hcengineering/platform","slug":"training-request-attachedto-not-found","errorCode":null,"errorMessage":"Training #${request.attachedTo} not found","messagePattern":"Training #(.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/training-resources/src/functions/trainingRequestObjectTitleProvider.ts","lineNumber":43,"sourceCode":"  doc?: TrainingRequest\n): Promise<string> {\n  const request = await client.findOne<TrainingRequest>(\n    training.class.TrainingRequest,\n    {\n      _id: ref\n    },\n    {\n      lookup: {\n        attachedTo: training.class.Training\n      }\n    }\n  )\n  if (request === undefined) {\n    throw new Error(`Training request #${ref} not found`)\n  }\n  const trainingObject = request.$lookup?.attachedTo\n  if (trainingObject === undefined) {\n    throw new Error(`Training #${request.attachedTo} not found`)\n  }\n\n  const revisionLabel = client.getHierarchy().getAttribute(trainingObject._class, 'revision').label\n  const revisionString = await translate(revisionLabel, {}, getCurrentLanguage())\n  return `${trainingObject.code} • ${trainingObject.title} • ${revisionString} ${trainingObject.revision}`\n}\n","sourceCodeStart":25,"sourceCodeEnd":50,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/training-resources/src/functions/trainingRequestObjectTitleProvider.ts#L25-L50","documentation":"After the request is found, the provider reads request.$lookup?.attachedTo — the parent Training resolved via lookup. If the lookup did not populate (undefined), the parent training cannot be resolved for the title. This usually means the training document was deleted or the lookup configuration did not fetch it.","triggerScenarios":"TrainingRequest exists but its attachedTo Training no longer exists, or the findOne lookup options did not populate $lookup.attachedTo.","commonSituations":"Orphaned requests after a training hard-delete; hierarchy/lookup misconfiguration in the model; data restored partially from backup.","solutions":["Verify the parent Training (request.attachedTo) exists in the database.","Check the model's lookup configuration so $lookup.attachedTo is populated by the query.","Clean up orphaned TrainingRequest documents whose parent trainings are gone.","Add a fallback title when the parent is missing instead of relying on lookup."],"exampleFix":"// before\nconst trainingObject = request.$lookup?.attachedTo\n// after\nconst trainingObject = request.$lookup?.attachedTo ?? await client.findOne(training.class.Training, { _id: request.attachedTo })","handlingStrategy":"validation","validationCode":"const parent = await client.findOne(training.class.Training, { _id: request.attachedTo })\nif (parent === undefined) return 'orphaned request'","typeGuard":"function hasAttachedParent<T extends { $lookup?: { attachedTo?: Doc } }>(r: T): boolean { return r.$lookup?.attachedTo !== undefined }","tryCatchPattern":"try { return await titleProvider(client, ref) } catch { return await fallbackTitle(client, ref) }","preventionTips":["Ensure lookup declarations populate $lookup.attachedTo","Cascade-delete or reassign requests when deleting trainings","Audit for orphaned requests after deletions"],"tags":["lookup","missing-object","training"],"backgroundTag":"referenced-object-not-found","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}