hcengineering/platform · warning
Modifications of reaction type are not allowed.
Error message
Modifications of reaction type are not allowed.
What it means
validateReactionUpdate inspects TxUpdateDoc for DocReaction and rejects any operation attempting to change the reactionType field, since reactions are immutable in kind after creation (change = remove + create a new reaction). Only other permitted fields may be updated.
Source
Thrown at server-plugins/rating/src/index.ts:98
const current = await this.provideFindAll(ctx, rating.class.DocReaction, {
attachedTo: create.attachedTo,
attachedToClass: create.objectClass
})
if (
current.some(
(it) =>
it.reactionType === create.attributes.reactionType &&
(it.value === create.attributes.value ||
(create.attributes.reactionType === ReactionKind.Emoji && it.emoji === create.attributes.emoji))
)
) {
throw new Error('Duplicate emoji reaction is not allowed.')
}
}
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 modifiedView on GitHub (pinned to 63e28dc964)
Solutions
- To change a reaction type, delete the existing DocReaction and create a new one with the desired type.
- Update the client to replace update-with-reactionType by remove+create flow.
- Remove reactionType from any migration/bulk update operation sets on DocReaction.
Example fix
// before
await client.updateDoc(rating.class.DocReaction, _id, { reactionType: ReactionKind.Emoji })
// after
await client.removeDoc(rating.class.DocReaction, space, _id)
await client.createDoc(rating.class.DocReaction, space, {
attachedTo: docId,
reactionType: ReactionKind.Emoji,
emoji: '👍'
}) Defensive patterns
Strategy: validation
Validate before calling
const ops: Record<string, any> = { ...update.operations }
if ('reactionType' in ops) {
throw new Error('Remove and re-create the reaction to change its type')
} Type guard
function isReactionTypeUpdate(upd: TxUpdateDoc<DocReaction>): boolean {
return upd.operations.reactionType !== undefined
} Try / catch
try {
await client.updateDoc(rating.class.DocReaction, _id, ops)
} catch (err) {
if (/Modifications of reaction type/.test(err.message)) {
await client.removeDoc(rating.class.DocReaction, space, _id)
await client.createDoc(rating.class.DocReaction, space, newReaction)
return
}
throw err
} Prevention
- Model reaction-type changes as remove+create in the client.
- Strip reactionType from any update operation sets.
- Document DocReaction immutability rules for UI developers.
- Add tests rejecting updates touching reactionType.
When it happens
Trigger: Submitting an update transaction on a DocReaction whose operations include reactionType — e.g. UI letting a user switch a Like to an Emoji in place, or migration code patching reactionType on existing rows.
Common situations: Frontend reaction picker updating the same doc instead of deleting and re-creating, bulk scripts normalizing reaction types, schema migrations adjusting reactionType values.
Related errors
- Duplicate emoji reaction is not allowed.
- Direct modifications of ratings are not allowed.
- Failed to load server config
- getDisplayMedia not supported
- No screen access granted
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4524b001b3261d7d.
Report an issue: GitHub.