The current implementation works until Blender 4.2LTS (which supports finished in Summer 2026), but breaks under Blender 4.5LTS.
The API for animation management changed heavily from Blender 4.4.
The following reports an analysis of Claude, suggesting how to migrate to the new API.
Root Cause: Blender 4.4+ "Slotted Actions" System
The single most important breaking change between Blender 4.2 (where the code works) and 4.5 (where it doesn't) is the Action Slot system introduced in Blender 4.4. It affects both skeleton #5 and gloria's shapekeys through the same pattern.
What changed in Blender 4.4
Before 4.4, an Action was a flat collection of F-Curves. action.fcurves was the complete, authoritative list.
In Blender 4.4, an Action became a layered structure where each animated datablock gets its own slot (identified by id_type and a name). The evaluator now reads:
obj.animation_data.action → the action
obj.animation_data.action_slot → which specific slot to read from (new!)
action.fcurves is kept as a compatibility shim that iterates over all slots combined, but the renderer only evaluates the slot pointed to by action_slot.
How the bug manifests
The broken pattern appears in merge.py:80-95 (prepare_target_actions):
# Step 1: Create action and assign to object
self.target_action = bpy.data.actions.new(self.action_name)
self.armature_obj.animation_data.action = self.target_action
# ↑ In 4.4+: creates a named SLOT for the armature in target_action,
# sets animation_data.action_slot → that named slot (currently EMPTY)
# Step 2: Create F-Curves via the legacy compat API
for source_fcurve in reference_action.fcurves:
self.target_action.fcurves.new(source_fcurve.data_path, index=source_fcurve.array_index)
# ↑ In 4.4+: fcurves.new() writes into the LEGACY/DEFAULT layer,
# NOT into the named slot that was just created for the armature
The same happens for shapekeys at merge.py:90-95:
self.shape_keys.animation_data.action = self.target_shapekeys_action
# ↑ Creates a named KEY slot; action_slot → that empty KEY slot
for source_fcurve in reference_shapekeys_action.fcurves:
self.target_shapekeys_action.fcurves.new(...)
# ↑ Writes into legacy layer, NOT into the KEY slot
Consequence: append_action() (merge.py:130-170) and perform_hold() (merge.py:98-128) write all keyframes into F-Curves that live in the legacy layer. The slot that the evaluator reads from (action_slot) is empty. During rendering, Blender finds no curves → the character is frozen in T-pose.
The identical issue exists in extract.py:170-185 (create_f_curves) and ArmatureUtils.py:192-209 (resample_blendshapes_action).
Secondary Issue: nla.bake parameter change (armature only)
In controllers.py:191-202:
bpy.ops.nla.bake(
...
bake_types={"POSE"},
)
In Blender 4.4+, bake_types changed from a set-enum to a plain enum string. The correct value is likely bake_types='POSE' (a string, not a set). If this call silently fails or raises a handled error, the inflected armature actions would contain no keyframes. This would explain the body not animating but is separate from the face issue.
Tertiary Issue: eevee.taa_render_samples renamed
In main.py:225:
bpy.context.scene.eevee.taa_render_samples = 2
In Blender 4.5's Eevee Next, the temporal anti-aliasing render sample setting was renamed. If this line raises AttributeError at runtime, the script aborts before reaching bpy.ops.render.render(animation=True) and no render is produced at all. If this is the case, any file previously written to the output path would be what the user sees.
Summary Table
Issue Location Affects Likelihood
action.fcurves.new() writes to wrong slot (4.4 API break) merge.py:86,94-95 Both armature + face Very high
nla.bake bake_types={"POSE"} → enum changed controllers.py:199 Armature only High
eevee.taa_render_samples renamed in 4.5 main.py:225 Prevents render entirely Medium
Fix direction
For the slot issue, you need to stop using action.fcurves.new() directly and instead create F-Curves through the slot that Blender assigned. After animation_data.action = action, the correct slot is at:
slot = obj.animation_data.action_slot
# Then create fcurves via the slot-aware API (Blender 4.4+)
The exact slot API surface differs between 4.4 and 4.5 (Blender is still stabilizing it), but the core idea is: any time you call action.fcurves.new(...), it should happen through the slot, not through the top-level action.fcurves compatibility shim. The same applies in append_action: target_action.fcurves.find(...) should still work (it searches all slots), but you need to confirm the fcurves were placed in the right slot to begin with.
main.py
How do I access or create fcurves in the new ActionSlot API? There is no such `fcurves` field in the ActionSlot class.
Good question — ActionSlot is the datablock identifier, not the F-Curve container. The actual F-Curves live one level deeper. Let me look up the exact API.
Agent:Blender 4.4 action slot fcurve API research
IN
Search the web for the Blender 4.4+ Python API for creating and accessing F-Curves using the new "Slotted Actions" / "Layered Actions" system. I need to know:
1. The full hierarchy: Action → slots → layers → strips → channelbag → fcurves. What are the exact attribute names and method signatures?
2. How to create an FCurve in a specific slot (the equivalent of `action.fcurves.new(data_path, index=i)` in the old API)
3. How to find/look up an FCurve in a specific slot (the equivalent of `action.fcurves.find(data_path, index=i)`)
4. What `strip.channelbag(slot)` does vs `strip.channelbags` - how to get or create a ChannelBag for a given slot
5. Does `action.fcurves.new()` still work in 4.4+ as a compat shim, or does it silently go to the wrong place?
6. Any official migration guide or example code from Blender docs/devtalk/git
Search terms to try: "blender 4.4 action slots python api fcurves", "blender slotted actions channelbag", "bpy.types.ActionStrip channelbag", site:docs.blender.org, developer.blender.org
Report the findings concisely with specific attribute/method names, signatures, and code examples if found.
deep-research skill
Waiting for the search results — will report as soon as they're in.
Bash
IN
cat > /private/tmp/claude-502/-Users-fanu01-admin-Documents-Code-MMS-Player-MMS-Player/b205fb51-cf8d-433d-9d2c-8cf2caa74db0/scratchpad/research_plan.txt << 'EOF'
DEEP RESEARCH: Blender 4.4+ Slotted Actions Python API
RESEARCH ANGLES:
1. Official Blender Python API documentation for Action slots, layers, strips
2. ChannelBag and FCurve creation/access in Slotted Actions system
3. ActionStrip.channelbag() method signature and behavior
4. Backward compatibility and migration guide from old fcurves.new() API
5. Community examples, developer discussions, and real-world usage patterns
KEY QUESTIONS TO RESOLVE:
- Complete hierarchy: Action → slots → layers → strips → channelbag → fcurves
- Attribute names: How to access each level?
- Creation: action.fcurves.new() vs strip.channelbag(slot).fcurves.new()
- Lookup: action.fcurves.find() vs strip.channelbag(slot).fcurves.find()
- strip.channelbag(slot) vs strip.channelbags difference
- Is old API a compat shim or deprecated?
EOF
cat /private/tmp/claude-502/-Users-fanu01-admin-Documents-Code-MMS-Player-MMS-Player/b205fb51-cf8d-433d-9d2c-8cf2caa74db0/scratchpad/research_plan.txt
OUT
DEEP RESEARCH: Blender 4.4+ Slotted Actions Python API
RESEARCH ANGLES:
1. Official Blender Python API documentation for Action slots, layers, strips
2. ChannelBag and FCurve creation/access in Slotted Actions system
3. ActionStrip.channelbag() method signature and behavior
4. Backward compatibility and migration guide from old fcurves.new() API
5. Community examples, developer discussions, and real-world usage patterns
KEY QUESTIONS TO RESOLVE:
- Complete hierarchy: Action → slots → layers → strips → channelbag → fcurves
- Attribute names: How to access each level?
- Creation: action.fcurves.new() vs strip.channelbag(slot).fcurves.new()
- Lookup: action.fcurves.find() vs strip.channelbag(slot).fcurves.find()
- strip.channelbag(slot) vs strip.channelbags difference
- Is old API a compat shim or deprecated?
Web SearchBlender developer.blender.org layered actions fcurves strip.channelbag
OUT
Web search results for query: "Blender developer.blender.org layered actions fcurves strip.channelbag"
Links: [{"title":"Layered Actions - Blender Developer Documentation","url":"https://developer.blender.org/docs/features/animation/animation_system/layered/"},{"title":"Python API - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/python_api/"},{"title":"Slotted Actions - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/upgrading/slotted_actions/"},{"title":"ActionChannelbagFCurves(bpy_struct) - Blender Python API","url":"https://docs.blender.org/api/current/bpy.types.ActionChannelbagFCurves.html"},{"title":"#125774 - Anim: add channel groups to layered actions - blender - Blender Projects","url":"https://projects.blender.org/blender/blender/pulls/125774"},{"title":"ActionChannelbag(bpy_struct) - Blender Python API","url":"https://docs.blender.org/api/current/bpy.types.ActionChannelbag.html"},{"title":"Automate Blender Animation with Python and CSV Data - CGWire's Blog","url":"https://blog.cg-wire.com/blender-programmatic-animation/"},{"title":"How to access fcurves in Blender 5.0 - Python Support - Blender Artists Community","url":"https://blenderartists.org/t/how-to-access-fcurves-in-blender-5-0/1623022"}]
I found relevant documentation from Blender's developer portal about layered actions, F-Curves, and channelbags. Here's what the search returned:
## Summary
The F-Curves in a keyframe StripData item are organized into Channelbags, each of which is earmarked for a different Slot via the Slots' numeric handles.
The Channelbag is what contains a set of F-Curves, and so what was the legacy Action data model now is represented by a Channelbag.
### Key Documentation Links Found:
1. **Layered Actions Documentation** - https://developer.blender.org/docs/features/animation/animation_system/layered/
- Core documentation about the layered actions system, strips, and channelbags
2. **Slotted Actions Upgrade Guide** - https://developer.blender.org/docs/release_notes/4.4/upgrading/slotted_actions/
- Migration guide showing how to work with channelbags and F-Curves in Blender 4.4+
3. **Python API Documentation** - https://docs.blender.org/api/current/bpy.types.ActionChannelbag.html
- API reference for ActionChannelbag and ActionChannelbagFCurves classes
The search results show that a Channelbag groups all F-curves belonging to a specific slot within a strip, and this is part of Blender's layered animation system introduced in version 4.4.
REMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.
Web Fetchhttps://blenderartists.org/t/how-to-access-fcurves-in-blender-5-0/1623022
Fetched from https://blenderartists.org/t/how-to-access-fcurves-in-blender-5-0/1623022
Web SearchBlender 4.4 5.0 "action.fcurves" backward compatibility compat shim
OUT
Web search results for query: "Blender 4.4 5.0 "action.fcurves" backward compatibility compat shim"
Links: [{"title":"Blender 5.0: Python API","url":"https://developer.blender.org/docs/release_notes/5.0/python_api/"},{"title":"How to access fcurves in Blender 5.0 - Python Support - Blender Artists Community","url":"https://blenderartists.org/t/how-to-access-fcurves-in-blender-5-0/1623022"},{"title":"Slotted Actions - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/upgrading/slotted_actions/"},{"title":"#146534 - Animation Fcurves are not visible in python or Outliner - blender - Blender Projects","url":"https://projects.blender.org/blender/blender/issues/146534"},{"title":"\"Render Selected Keyframes\" not working in Blender 5.0 · Issue #124 · p2or/blender-loom","url":"https://github.com/p2or/blender-loom/issues/124"},{"title":"Blender 4.4: Python API","url":"https://developer.blender.org/docs/release_notes/4.4/python_api/"},{"title":"How to access fcurves in Blender 5.0 - #8 by david_for_you - Python Support - Blender Artists Community","url":"https://blenderartists.org/t/how-to-access-fcurves-in-blender-5-0/1623022/8"},{"title":"'Action' object has no attribute 'fcurves' error on Blender 5.0 · Issue #97 · dtzxporter/cast","url":"https://github.com/dtzxporter/cast/issues/97"}]
Based on the search results, here's what I found about `action.fcurves` backward compatibility between Blender 4.4 and 5.0:
## Key Findings:
The legacy Action API has been removed in Blender 5.0, which covered the properties action.fcurves, action.groups, and action.id_root.
However, in Blender 4.4, the legacy code that worked in older versions still functions, and the properties act as a proxy for the data in action.layers[0].strips[0].channelbag(action.slots[0]), creating the layer, strip, and slot if necessary. This means **Blender 4.4 provided backward compatibility** for the old API.
## No Compatibility Shim in 5.0:
Unlike Blender 4.4's proxy approach, there is no compatibility shim in Blender 5.0. To help with migration, Blender 5.0 introduced new functions like channelbag.fcurves.new() and action.fcurve_ensure_for_datablock() with a group_name parameter to make it simpler to port code from the legacy Action API to the current one.
For upgrading existing code, instead of accessing action.fcurves directly, you should use channelbag = anim_utils.action_ensure_channelbag_for_slot(action, action_slot) and then access channelbag.fcurves.
REMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.
Web Search"action.layers" "layer.strips" "strip.channelbag" Blender complete example code
OUT
Web search results for query: ""action.layers" "layer.strips" "strip.channelbag" Blender complete example code"
Links: [{"title":"Layered Actions - Blender Developer Documentation","url":"https://developer.blender.org/docs/features/animation/animation_system/layered/"},{"title":"Python API - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/python_api/"},{"title":"Slotted Actions - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/upgrading/slotted_actions/"},{"title":"Automate Blender Animation with Python and CSV Data - CGWire's Blog","url":"https://blog.cg-wire.com/blender-programmatic-animation/"},{"title":"Automate Blender Animation with Python and CSV Data","url":"https://cgwire.ghost.io/blender-programmatic-animation/"},{"title":"ActionChannelbags(bpy_struct) - Blender Python API","url":"https://docs.blender.org/api/current/bpy.types.ActionChannelbags.html"},{"title":"ActionChannelbag(bpy_struct) - Blender Python API","url":"https://docs.blender.org/api/current/bpy.types.ActionChannelbag.html"}]
Based on the search results, I found several complete example code snippets for working with `action.layers`, `layer.strips`, and `strip.channelbag` in Blender. Here are the key examples:
## Basic Creation Pattern
Create a layer, strip, and channelbag with: `layer = action.layers.new("Layer")`, `strip = layer.strips.new(type='KEYFRAME')`, and `channelbag = strip.channelbag(slot, ensure=True)`. F-Curves and Groups are created on the channelbag with the same API as previously on `action`.
## Complete Example with Keyframe Interpolation
Here's a practical complete example from the CGWire blog that demonstrates the full workflow:
The example retrieves a Camera object, clears existing animation data, reads keyframe data from a CSV file, sets the camera's location, inserts keyframes, and then accesses the action to set interpolation: `action = obj.animation_data.action`, `slot = action.slots[0]`, `channelbag = action.layers[0].strips[0].channelbag(slot)`, then iterates over F-curves to set keyframe interpolation to "LINEAR".
## Finding and Removing F-Curves
F-Curves can be found and removed from the appropriate channelbag using: `strip = action.layers[0].strips[0]`, `channelbag = strip.channelbag(slot)`, `fcurve = channelbag.fcurves.find("location", index=1)`, and `channelbag.fcurves.remove(fcurve)`.
## Important Notes
The `fcurve.update()` call is not optional—Blender caches curve data internally, and skipping this call means changes may not take effect or may produce inconsistent results.
REMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.
Web SearchBlender "action.fcurves" 4.4 legacy API proxy "first slot" backward compat
OUT
Web search results for query: "Blender "action.fcurves" 4.4 legacy API proxy "first slot" backward compat"
Links: [{"title":"Slotted Actions - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/upgrading/slotted_actions/"},{"title":"Blender 4.4: Python API","url":"https://developer.blender.org/docs/release_notes/4.4/python_api/"},{"title":"Animation & Rigging - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/4.4/animation_rigging/"},{"title":"Action(ID) — UPBGE/Blender Python API","url":"https://upbge.org/docs/latest/api/bpy.types.Action.html"},{"title":"Python API - Blender Developer Documentation","url":"https://developer.blender.org/docs/release_notes/5.0/python_api/"},{"title":"#146534 - Animation Fcurves are not visible in python or Outliner - blender - Blender Projects","url":"https://projects.blender.org/blender/blender/issues/146534"},{"title":"Blender 4.4 - Slotted Actions - Feedback - Page 3 - Feature & Design Feedback - Developer Forum","url":"https://devtalk.blender.org/t/blender-4-4-slotted-actions-feedback/38906?page=3"},{"title":"Action(ID) - Blender Python API","url":"https://docs.blender.org/api/current/bpy.types.Action.html"}]
Based on the search results, here's the information about Blender's `action.fcurves` legacy API proxy and backward compatibility in version 4.4:
## Legacy API Proxy for `action.fcurves`
In Blender 4.4, `action.fcurves` is an alias for `channelbag_for_first_slot.fcurves`. This is part of the backward compatibility layer that was introduced with the new slotted actions system.
## How It Works
The properties used there will act as a proxy for the data in `action.layers[0].strips[0].channelbag(action.slots[0])`, which operates on the first slot automatically. The API will operate on the F-Curves/Groups for the first slot only, and the creation of an F-Curve or Group via this API will also create a slot named "Legacy Slot".
## Backward Compatibility
The code shown for "Blender 4.3 and older" will work in Blender 4.4 as well. This means that existing scripts using the legacy `action.fcurves` API continue to function without modification.
## Deprecation Note
It's worth noting that the legacy Action API has been removed in Blender 5.0, which covered the properties `action.fcurves`, `action.groups`, and `action.id_root`, so this backward compatibility layer is specific to the 4.4 release cycle.
REMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.
Excellent! I now have comprehensive information. Let me compile the findings with proper citations:
RESEARCH REPORT: Blender 4.4+ Python API for Slotted Actions / Layered Actions
Based on my comprehensive web research, here are the detailed findings on the new F-Curves API hierarchy in Blender 4.4+:
1. COMPLETE HIERARCHY: Action → Slots → Layers → Strips → ChannelBag → FCurves
The complete structure and exact attribute names:
action.slots # ActionSlots collection
slot = action.slots[0] # or action.slots.new(id_type='OBJECT', name="MySlot")
action.layers # ActionLayers collection
layer = action.layers.new("MyLayer") # Create a layer
layer.strips # ActionStrips collection (KeyframeActionStrip items)
strip = layer.strips.new(type='KEYFRAME') # Create keyframe strip
strip.channelbag(slot, ensure=True) # Get/create ChannelBag for specific slot
# Returns ActionChannelbag object
channelbag.fcurves # ActionChannelbagFCurves collection
channelbag.groups # ActionChannelbagGroups collection (for channel groups)
2. CREATING AN FCURVE IN A SPECIFIC SLOT
# Old API (Blender 4.3 and earlier):
fcurve = action.fcurves.new(data_path="location", index=2)
# New API (Blender 4.4+):
action = bpy.data.actions["MyAction"]
slot = action.slots[0]
layer = action.layers[0]
strip = layer.strips[0]
channelbag = strip.channelbag(slot, ensure=True)
fcurve = channelbag.fcurves.new("location", index=2)
Method Signature:
channelbag.fcurves.new(data_path, *, index=0, group_name='')
Parameters:
data_path (string, required) – F-Curve data path (e.g., "location", "rotation_euler")
index (int, optional, default=0) – Array index for vector/quaternion properties
group_name (string, optional) – Channel group name; creates group if it doesn't exist
Returns: FCurve object
3. FINDING/LOOKING UP AN FCURVE IN A SPECIFIC SLOT
# Old API:
fcurve = action.fcurves.find("location", index=2)
# New API:
channelbag = strip.channelbag(slot, ensure=True)
fcurve = channelbag.fcurves.find("location", index=2)
Method Signature:
channelbag.fcurves.find(data_path, *, index=0)
Parameters:
data_path (string, required) – The F-Curve data path
index (int, optional, default=0) – Array index
Returns: FCurve object or None if not found
4. strip.channelbag(slot) vs strip.channelbags DIFFERENCE
strip.channelbag(slot, ensure=False) – A method that returns a single ActionChannelbag object for a specific slot. The ensure boolean parameter determines whether to create it if missing. This is how you access/create F-Curves for a specific slot.
strip.channelbags – A collection (ActionChannelbags) containing all channelbags in the strip. You use this to iterate over all channelbags or manage them as a collection (add/remove operations).
# Access specific slot's channelbag:
cb = strip.channelbag(slot, ensure=True)
# Iterate all channelbags:
for channelbag in strip.channelbags:
for fcurve in channelbag.fcurves:
print(fcurve.data_path)
5. BACKWARD COMPATIBILITY: action.fcurves.new() IN 4.4+
In Blender 4.4: action.fcurves works as a backward-compatible legacy API proxy.
Calling action.fcurves.new() transparently creates the animation in action.layers[0].strips[0].channelbag(action.slots[0])
It automatically creates a slot named "Legacy Slot" if needed
The old API operates on the first slot only
Existing scripts using the legacy API continue to work without modification
In Blender 5.0: The legacy API has been completely removed. action.fcurves, action.groups, and action.id_root no longer exist.
For forward compatibility with Blender 5.0+, use the new explicit API or migration helpers like bpy_extras.anim_utils.action_ensure_channelbag_for_slot().
6. OFFICIAL MIGRATION GUIDE & EXAMPLE CODE
Migration pattern from Blender 4.3 to 4.4+:
# OLD CODE (Blender 4.3 and earlier)
action = bpy.data.actions["MyAction"]
fcurve = action.fcurves.new("location", index=0, action_group="Location")
# NEW CODE (Blender 4.4+)
import bpy
from bpy_extras import anim_utils
action = bpy.data.actions["MyAction"]
slot = action.slots[0] # or create: action.slots.new(id_type='OBJECT', name="SlotName")
# Option A: Explicit layer/strip access
layer = action.layers[0] # or action.layers.new("Layer")
strip = layer.strips[0] # or layer.strips.new(type='KEYFRAME')
channelbag = strip.channelbag(slot, ensure=True)
# Option B: Using helper (Blender 5.0 recommended)
channelbag = anim_utils.action_ensure_channelbag_for_slot(action, slot)
# Create F-Curve with group (parameter now called group_name, not action_group)
fcurve = channelbag.fcurves.new("location", index=0, group_name="Location")
Additional Blender 5.0 helper:
# New method: action.fcurve_ensure_for_datablock()
fcurve = action.fcurve_ensure_for_datablock(data_path="location", index=0, group_name="Location")
KEY SOURCES
Slotted Actions - Blender Developer Documentation
Layered Actions - Blender Developer Documentation
Python API Release Notes - Blender 4.4
Python API Release Notes - Blender 5.0
ActionChannelbag - Blender Python API
ActionChannelbagFCurves - Blender Python API
Action(ID) - Blender Python API
How to access fcurves in Blender 5.0 - Blender Artists Community
Automate Blender Animation with Python and CSV Data
Here is the confirmed structure from the Blender 4.4 developer docs.
The Hierarchy
Action has no flat fcurves anymore. The path to F-Curves goes through four levels:
Action
└── .layers[] → ActionLayer
└── .strips[] → ActionStrip (KeyframeActionStrip)
└── .channelbag(slot, ensure=True) → ActionChannelBag
└── .fcurves → the F-Curves
ActionSlot is just the identifier (holds id_type and name). The actual data lives in ActionChannelBag, which is keyed per slot inside each strip.
Creating F-Curves
# Get or create a slot for the animated datablock
# id_type: 'ARMATURE', 'KEY', 'OBJECT', etc.
slot = action.slots.new(id_type='ARMATURE', name="skeleton")
# Get or create the layer/strip/channelbag structure
if not action.layers:
layer = action.layers.new("Layer")
else:
layer = action.layers[0]
if not layer.strips:
strip = layer.strips.new(type='KEYFRAME')
else:
strip = layer.strips[0]
channelbag = strip.channelbag(slot, ensure=True) # ensure=True creates it if absent
# Now create an F-Curve (same signature as before)
fcurve = channelbag.fcurves.new("pose.bones[\"Bone_Root\"].rotation_euler", index=0)
Shortcut via bpy_extras (cleaner, handles the layer/strip boilerplate):
from bpy_extras import anim_utils
channelbag = anim_utils.action_ensure_channelbag_for_slot(action, slot)
fcurve = channelbag.fcurves.new(data_path, index=i)
Finding F-Curves
channelbag = strip.channelbag(slot) # ensure=False (default) → returns None if absent
if channelbag:
fcurve = channelbag.fcurves.find(data_path, index=i)
Getting the slot when assigning an action to an object
When you do obj.animation_data.action = action, Blender 4.4 auto-creates a slot for the object's type. Retrieve it with:
obj.animation_data.action = action
slot = obj.animation_data.action_slot # ← the auto-created slot
Compat shim status
Version action.fcurves.new()
≤ 4.3 Native, authoritative
4.4 – 4.x Legacy shim → writes into layers[0].strips[0].channelbag(slots[0])
5.0 Removed entirely
So the shim still works in 4.4/4.5, but it silently assumes slots[0] is the right one. It is safe as long as your action has exactly one slot and it was created before the first fcurves.new() call — which is fragile. Using the explicit slot API (above) is the correct path forward.
The current implementation works until Blender 4.2LTS (which supports finished in Summer 2026), but breaks under Blender 4.5LTS.
The API for animation management changed heavily from Blender 4.4.
The following reports an analysis of Claude, suggesting how to migrate to the new API.