Why is the string property added to f-curve read-only
Assigning to Existing Classes
Custom properties can be added to any subclass of an ID, Bone and
PoseBone

Neither are bones, so leaving that aside, can see below ID is subclass of Object not FCurve, and as such is the property is not &quot;wired up&quot; as a property on the fcurve.
&gt;&gt;&gt; issubclass(bpy.types.Object, (bpy.types.ID,))
True

&gt;&gt;&gt; issubclass(bpy.types.FCurve, (bpy.types.ID,))
False

another test for this would be trying to assign ID properties to an instance.  This is how a non default value of a property is stored in blend file.
For example, for an Object type
&gt;&gt;&gt; C.object[&quot;foo&quot;] = 1

but not for an FCurve
&gt;&gt;&gt; D.actions['CubeAction'].fcurves[0]
bpy.data.actions['CubeAction']...FCurve

&gt;&gt;&gt; D.actions['CubeAction'].fcurves[0][&quot;foo&quot;] = 1
Traceback (most recent call last):
  File &quot;&lt;blender_console&gt;&quot;, line 1, in &lt;module&gt;
TypeError: bpy_struct[key] = val: id properties not supported for this type