No suitably rooted paths error when trying to set action on object I'm trying to place a copy of an action onto another object.
My code seems to work, except when I try to set the action on the new object.
(I'm copying the animated viewport display rgb values, from the material of source_cube to the viewport display colors of target_cube)
The error that eludes me is:
Error: Could not set action 'the_new_action.002' onto ID 'OBtarget', as it does not have suitably rooted paths for this purpose
Any clues what I'm missing here?
import bpy

# Gets the action from material of object
def get_material_action(object):
    # current_object, material, action
    current_material = object.material_slots[0].material
    action = current_material.animation_data.action
    print ('getter: found:', action.name)
    return action
    
    #print ('current object', current_object.name)
    #print ('current material', current_material.name)
    #print ('current material action', current_material_action.name)

# Copies the action
def copy_action(action):
    current_action = bpy.data.actions.get(action)
    
    ### Create a copy of that action
    new_action = current_action.copy()
    new_action.name = 'the_new_action'
    print ('copier made: ', new_action.name)
    return new_action
    
# Sets the action on material of object    
def set_action(object, new_action):
    current_material = object.material_slots[0].material
    # create empty action
    object.animation_data_create()
    object.animation_data.action = bpy.data.actions.get(new_action.name)


# Define source and target objects
source_object = bpy.data.objects['source']
target_object = bpy.data.objects['target']


# get current action from source 
# Then copy and name it
# Then set action on target
source_action = get_material_action(source_object)    
new_action = copy_action(source_action.name)
set_action(target_object, new_action)



print ('done')
Action ID root
The error is informing of attempting  to link an action which expects to be for a material onto an object.
The created action from keyframing property of  a material has 'MATERIAL' set as its ID root.

ID root
Type of ID block that action can  be used on - DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING

Py console example
&gt;&gt;&gt; source = C.object
&gt;&gt;&gt; mat = source.active_material
&gt;&gt;&gt; mat
bpy.data.materials['Material']

&gt;&gt;&gt; action = mat.animation_data.action
&gt;&gt;&gt; action
bpy.data.actions['MaterialAction']

&gt;&gt;&gt; action.id_root
'MATERIAL'

An object's action  would expect this value to be 'OBJECT'.
Material action -&gt; Object action
Example, material action with only keyframes for  diffuse_color of material
&gt;&gt;&gt; for f in action.fcurves:
...     f.data_path, f.array_index
...     
('diffuse_color', 0)
('diffuse_color', 1)
('diffuse_color', 2)
('diffuse_color', 3)

the data path from an object to &quot;viewport color&quot; is  color
At the very simplest, could as above copy the action, iterate over the fcurves, make our necessary datapath change, set object id root  and assign to the object.
action = action.copy()
for fc in action.fcurves:
    fc.data_path.replace(&quot;diffuse_color&quot;, &quot;color&quot;)
action.id_root = 'OBJECT' 

Context
Customary in blender is to use the active object as a source and other selected objects as the destination.
source = context.object
targets = context.selected_objects
targets.remove(source)

for operators, having a poll method removes the need to test for  context.object being None