{"record":{"id":"1cf7cf16778ced73","repo":"hcengineering/platform","slug":"reaction-value-modification-is-required","errorCode":null,"errorMessage":"Reaction value modification is required.","messagePattern":"Reaction value modification is required\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server-plugins/rating/src/index.ts","lineNumber":111,"sourceCode":"    }\n  }\n\n  private async validateReactionUpdate (ctx: MeasureContext, upd: TxUpdateDoc<DocReaction>): Promise<void> {\n    if (upd.operations.reactionType !== undefined) {\n      throw new Error('Modifications of reaction type are not allowed.')\n    }\n    // Find current reaction tried to be modified\n    const current = (\n      await this.provideFindAll(ctx, rating.class.DocReaction, {\n        _id: upd.objectId,\n        _class: upd.objectClass\n      })\n    ).shift()\n    if (current === undefined) {\n      throw new Error('Reaction not found.')\n    }\n    if (upd.operations.value === undefined || upd.operations.value < 0 || upd.operations.value > 10) {\n      throw new Error('Reaction value modification is required.')\n    }\n  }\n\n  private async validateReactionRemove (ctx: MeasureContext, upd: TxRemoveDoc<DocReaction>): Promise<void> {\n    // Find current reaction tried to be modified\n    // const current = (\n    //   await this.provideFindAll(ctx, rating.class.DocReaction, {\n    //     _id: upd.objectId,\n    //     _class: upd.objectClass\n    //   })\n    // ).shift()\n    // if (current === undefined) {\n    // No error, already removed\n    // }\n    // if (current.reactionType === ReactionKind.Star) {\n    //   throw new Error('Star reactions could not be removed.')\n    // }\n  }","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/server-plugins/rating/src/index.ts#L93-L129","documentation":"validateReactionUpdate requires that an update to a DocReaction carries a valid new 'value'. The throw fires when operations.value is undefined or outside the allowed 0..10 range, so invalid value updates are rejected before they reach storage.","triggerScenarios":"Sending TxUpdateDoc<DocReaction> with operations that omit 'value', set it to a negative number, or set it greater than 10 (e.g. updating only 'emoji' without including value).","commonSituations":"Client updates an emoji reaction thinking only 'emoji' changes; UI sends a partial operations object; off-by-one rating inputs allowing 10+ or -1; misconfigured rating scale assumptions.","solutions":["Always include a valid operations.value (integer 0-10) in every DocReaction update tx","Clamp the value in the client before sending: Math.min(10, Math.max(0, value))","If only changing emoji, re-send the existing reaction value along with the new emoji"],"exampleFix":"// before\nconst ops = { emoji: '🎉' }\n// after\nconst ops = { emoji: '🎉', value: currentReaction.value } // value must be 0..10","handlingStrategy":"validation","validationCode":"function canUpdateReaction(ops: { value?: number }): boolean {\n  return ops.value !== undefined && ops.value >= 0 && ops.value <= 10\n}","typeGuard":"function hasValidReactionValue(ops: TxUpdateDoc<DocReaction>['operations']): ops is { value: number } & typeof ops {\n  return typeof ops.value === 'number' && ops.value >= 0 && ops.value <= 10\n}","tryCatchPattern":"try {\n  await tx.updateDoc(reactionClass, { _id: id }, ops)\n} catch (err) {\n  if ((err as Error).message === 'Reaction value modification is required.') {\n    throw new ValidationError('reaction value must be 0..10')\n  }\n  throw err\n}","preventionTips":["Always carry forward the existing value when updating other fields like emoji","Clamp user input to 0..10 in the UI before constructing the tx","Write a client-side unit test covering boundaries 0, 10, -1, 11","Model the value as a branded 0..10 type to catch invalid values at compile time"],"tags":["tx-validation","schema-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}