hcengineering/platform · error

Reaction value modification is required.

Error message

Reaction value modification is required.

What it means

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.

Source

Thrown at server-plugins/rating/src/index.ts:111

    }
  }

  private async validateReactionUpdate (ctx: MeasureContext, upd: TxUpdateDoc<DocReaction>): Promise<void> {
    if (upd.operations.reactionType !== undefined) {
      throw new Error('Modifications of reaction type are not allowed.')
    }
    // Find current reaction tried to be modified
    const current = (
      await this.provideFindAll(ctx, rating.class.DocReaction, {
        _id: upd.objectId,
        _class: upd.objectClass
      })
    ).shift()
    if (current === undefined) {
      throw new Error('Reaction not found.')
    }
    if (upd.operations.value === undefined || upd.operations.value < 0 || upd.operations.value > 10) {
      throw new Error('Reaction value modification is required.')
    }
  }

  private async validateReactionRemove (ctx: MeasureContext, upd: TxRemoveDoc<DocReaction>): Promise<void> {
    // Find current reaction tried to be modified
    // const current = (
    //   await this.provideFindAll(ctx, rating.class.DocReaction, {
    //     _id: upd.objectId,
    //     _class: upd.objectClass
    //   })
    // ).shift()
    // if (current === undefined) {
    // No error, already removed
    // }
    // if (current.reactionType === ReactionKind.Star) {
    //   throw new Error('Star reactions could not be removed.')
    // }
  }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Always include a valid operations.value (integer 0-10) in every DocReaction update tx
  2. Clamp the value in the client before sending: Math.min(10, Math.max(0, value))
  3. If only changing emoji, re-send the existing reaction value along with the new emoji

Example fix

// before
const ops = { emoji: '🎉' }
// after
const ops = { emoji: '🎉', value: currentReaction.value } // value must be 0..10
Defensive patterns

Strategy: validation

Validate before calling

function canUpdateReaction(ops: { value?: number }): boolean {
  return ops.value !== undefined && ops.value >= 0 && ops.value <= 10
}

Type guard

function hasValidReactionValue(ops: TxUpdateDoc<DocReaction>['operations']): ops is { value: number } & typeof ops {
  return typeof ops.value === 'number' && ops.value >= 0 && ops.value <= 10
}

Try / catch

try {
  await tx.updateDoc(reactionClass, { _id: id }, ops)
} catch (err) {
  if ((err as Error).message === 'Reaction value modification is required.') {
    throw new ValidationError('reaction value must be 0..10')
  }
  throw err
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/1cf7cf16778ced73. Report an issue: GitHub.