Verified against 1.138.0 (also present in 1.137.0). All three are in the prototype-reaction path, and none of them can be caught by a type checker or a mocked test — the type says one thing and setReactionsAsync says another, so they only surface against a live document.
Runtime error text below is quoted verbatim from setReactionsAsync.
1. EasingFunctionSpring.initialVelocity is rejected
transition: {
type: 'SMART_ANIMATE',
duration: 0.4,
easing: {
type: 'CUSTOM_SPRING',
easingFunctionSpring: { mass: 1, stiffness: 200, damping: 20, initialVelocity: 0 },
},
}
Unrecognized key(s) in object: 'initialVelocity'
at [0].actions[0].transition.easing.easingFunctionSpring
Dropping initialVelocity succeeds, and a subsequent read returns only { mass, stiffness, damping } — the field never comes back either.
This one is costly in both directions, because all four fields are declared required: sending the three the runtime wants fails a type check (or any schema derived from these typings), and sending four fails Figma.
EasingFunctionSpring has exactly one referent in the file — Easing.easingFunctionSpring — so nothing else depends on the extra field. PhysicalSpring, declared a few lines below, is already exactly the accepted shape:
interface PhysicalSpring {
readonly mass: number
readonly stiffness: number
readonly damping: number
}
2. A hover trigger's deprecatedVersion is rejected
trigger: { type: 'MOUSE_ENTER', delay: 0.25, deprecatedVersion: false }
Unrecognized key(s) in object: 'deprecatedVersion' at [0].trigger
Reading back a MOUSE_ENTER trigger authored today does not include the field, so this looks like it is only ever an output marker for legacy hover triggers. If that is right, the type is still correct for a read and only misleading for a write — marking it as such (or noting it in a doc comment) would be enough.
3. UPDATE_MEDIA_RUNTIME.destinationId is optional in the type, required at runtime
The SKIP_FORWARD | SKIP_BACKWARD and SKIP_TO variants declare destinationId?: string | null, but omitting it is refused:
actions: [{ type: 'UPDATE_MEDIA_RUNTIME', mediaAction: 'SKIP_FORWARD', amountToSkip: 5 }]
Required value missing at [0].actions[0].destinationId
Supplying a valid media destination makes the same call succeed, and all three variants then round-trip intact. Only the first variant (PLAY | PAUSE | …) declares destinationId as required today; the other two appear to need it too.
Found while making prototype reactions round-trip losslessly in Figwright, an MCP server for Figma — every claim above is from a real document, not from reading the .d.ts. Happy to supply more detail on any of them.
Verified against 1.138.0 (also present in 1.137.0). All three are in the prototype-reaction path, and none of them can be caught by a type checker or a mocked test — the type says one thing and
setReactionsAsyncsays another, so they only surface against a live document.Runtime error text below is quoted verbatim from
setReactionsAsync.1.
EasingFunctionSpring.initialVelocityis rejectedDropping
initialVelocitysucceeds, and a subsequent read returns only{ mass, stiffness, damping }— the field never comes back either.This one is costly in both directions, because all four fields are declared required: sending the three the runtime wants fails a type check (or any schema derived from these typings), and sending four fails Figma.
EasingFunctionSpringhas exactly one referent in the file —Easing.easingFunctionSpring— so nothing else depends on the extra field.PhysicalSpring, declared a few lines below, is already exactly the accepted shape:2. A hover trigger's
deprecatedVersionis rejectedReading back a
MOUSE_ENTERtrigger authored today does not include the field, so this looks like it is only ever an output marker for legacy hover triggers. If that is right, the type is still correct for a read and only misleading for a write — marking it as such (or noting it in a doc comment) would be enough.3.
UPDATE_MEDIA_RUNTIME.destinationIdis optional in the type, required at runtimeThe
SKIP_FORWARD | SKIP_BACKWARDandSKIP_TOvariants declaredestinationId?: string | null, but omitting it is refused:Supplying a valid media destination makes the same call succeed, and all three variants then round-trip intact. Only the first variant (
PLAY | PAUSE | …) declaresdestinationIdas required today; the other two appear to need it too.Found while making prototype reactions round-trip losslessly in Figwright, an MCP server for Figma — every claim above is from a real document, not from reading the
.d.ts. Happy to supply more detail on any of them.