Quick answer: Cached Pose node holds last update's pose; using it after a state transition shows old animation frame - rebuild dependency graph.
If you are searching for how to fix unreal anim blueprint anim graph cache pose stale, you are in the right place. This is a recurring issue in Unreal Engine that catches both new and experienced developers. The behavior looks like a deep engine bug, but the root cause is usually a small interaction between two systems that the documentation does not call out. Below is the full breakdown of the symptom, why it happens, a step-by-step fix you can apply today, and the diagnostic workflow to confirm everything is working.
The Symptom
Your Anim Blueprint uses a Cached Pose to share a base pose between two branches (upper body and lower body). After a state transition, the upper body briefly shows the previous animation frame before catching up - a one-frame lag.
This kind of symptom tends to be deterministic in the editor but harder to reproduce in shipped builds, where the conditions that trigger it depend on player behavior, hardware, or timing that you cannot fully control during development. If you have a player bug report that matches the description above, the same fix usually applies. The cleanest approach is to set up an isolated test scene that reproduces the problem on every run before you change anything in your main project.
Root Cause
Cached Pose nodes save the pose at their execution point. If a Save Cached Pose is positioned before the State Machine that drives the actual animation, the cache holds the pose from the previous tick (before the state change). Downstream Use Cached Pose nodes read this stale data.
This pattern shows up in many areas of Unreal Engine where two subsystems communicate through a shared but loosely-typed contract. The first subsystem reports success at its layer; the second subsystem silently rejects or transforms the data without an error. Because there is no exception at the boundary, the only visible evidence is the wrong output at the end of the pipeline, which is where most developers start their investigation. Tracing the bug backwards through the layers reveals the actual mismatch, and once you have done it once for a particular pair of subsystems, the same diagnostic technique applies to related bugs in the same area.
The Fix
Step 1. Move Save Cached Pose AFTER the State Machine in the graph execution order. The cache then captures the current state's pose.
// Correct Anim Graph structure (visual)
//
// State Machine 'Locomotion' (Idle/Walk/Run)
// ↓
// Save Cached Pose 'BaseLocomotion' ← AFTER state machine
// ↓
// [Used by upper body and lower body branches]
//
// Upper Body Branch:
// Layered Blend Per Bone
// Base Pose: Use Cached Pose 'BaseLocomotion'
// Blend Pose: Upper Body Override (e.g., aim, attack)
// → Output Pose
//
// Lower Body Branch:
// Use Cached Pose 'BaseLocomotion'
// → Lower Body Output
Step 2. Use Linked Anim Layers instead of cached poses for cross-branch sharing - layers re-evaluate per tick and don't have the staleness issue.
// Linked Anim Layers - cleaner alternative
// Define interface: UMyAnimLayerInterface
// GetBasePose() returns FPoseLink
//
// In main AnimBP, implement GetBasePose returning State Machine output
//
// In Upper/Lower body AnimBPs:
// Implement same interface (per-layer)
// GetBasePose forwards to parent
//
// In gameplay code:
GetMesh()->LinkAnimClassLayers(UpperBodyLayerClass);
GetMesh()->LinkAnimClassLayers(LowerBodyLayerClass);
// Layers automatically share pose data via interface
Step 3. Verify execution order via the Anim Graph debugger (Window → Animation → AnimBP Debug). The pose flow should show state machine → cache → consumers.
Diagnostic workflow
Before you call the bug fixed, walk through this short checklist to confirm the fix addresses the actual cause and not a similar-looking symptom. First, reproduce the issue deterministically in a minimal scene. If you cannot get the same failure twice in a row, your fix attempts will be hard to evaluate, so spend the time to lock down a clean repro before changing any code. Second, apply only the fix - resist the urge to also clean up surrounding code. A single-variable change makes it obvious which edit resolved the symptom. Third, run the repro three or more times after the fix to confirm the issue does not return intermittently.
If the fix works in the editor but the symptom returns in a build, the most common explanation is a configuration difference. Build settings, asset import flags, and platform-specific feature toggles can change behavior between editor playthrough and shipped binary. Add platform-conditional logging around the fix code, ship a debug build with the logs enabled, and verify the relevant configuration values match expectations on the target device. Capturing logs from a few players on different hardware quickly reveals platform-specific deviations.
Why this happens
This bug class lives at the boundary between two Unreal Engine subsystems. The first system reports success at its layer; the second system silently rejects or transforms the data without raising an error. Because the boundary is not loud about its expectations, the symptom only appears at the end of the pipeline. The fix above addresses the configuration mismatch at the boundary - once the two systems agree on the data contract, the symptom disappears immediately.
This is also why the bug feels disproportionate to the fix. A one-line change resolves what looked like a fundamental engine problem because the engine was working correctly all along - it was just being asked to do something slightly different from what the calling code expected. Understanding the boundary contract is the durable lesson; the specific fix is the immediate payoff. Once you have internalized a few of these contract patterns, you start spotting them faster in subsequent bug investigations and your time-to-fix drops dramatically.
Verifying the fix
Reproduce the original symptom in isolation before applying the fix. If you cannot reliably reproduce, you cannot reliably verify - and you risk shipping a fix that addresses a different bug. Start with a minimal scene or scenario that triggers the issue every time, apply the change above, and run the same scenario at least three times to confirm the symptom is gone. Once the minimal repro is clean, retest in the full game to confirm the fix doesn't regress anything else.
For shipping games, follow a staged rollout. Push the fix to five to ten percent of players first, monitor the affected metric (crash rate, error log frequency, gameplay telemetry) for twenty-four to forty-eight hours, and expand only if the data confirms the fix without regressions. A staged rollout is cheap insurance against an interaction you did not anticipate in your test environment, and the additional data from real players surfaces edge cases your QA pass never thought to try.
Capturing the bug from players
The hardest part of fixing this kind of issue is getting a player report that includes enough context to reproduce. Most players describe the symptom in their own words and omit the build number, scene name, hardware, or input sequence that triggered it. Without those details, you are guessing at the conditions and that guesswork is where most engineering time is wasted on production bugs.
A bug reporting SDK like Bugnet for Unreal Engine captures the build SHA, scene name, recent logs, device specs, frame rate, and a screenshot automatically whenever a player files a report. With that bundle attached, you can reproduce the bug locally instead of guessing - typically the difference between a one-day fix and a one-week investigation. The same SDK also catches unhandled errors automatically, so you get the report even when the player does not file one, which catches the silent failures that never make it to support emails.
Edge cases to watch for
The same root cause can produce slightly different symptoms in adjacent systems. After fixing the case you found, spend thirty minutes searching your project for similar patterns - the same API called with different arguments, the same data flow with a different entity type, or the same lifecycle issue in a sibling module. Each match is a candidate for the same fix, or a related fix that prevents future bugs of the same class. Building this catalog of 'we've seen this before' pattern is valuable institutional knowledge that compounds with each project.
Pay extra attention to boundary conditions - the first frame, the last frame, zero or maximum values, and the transition between two states. These are where engines often have undocumented behavior, and where regression tests pay the highest dividend. A test that exercises the boundary catches the subtle regressions that look like new bugs but are really the original returning. Add one or two of these boundary tests after every bug fix; they earn their keep over the long life of the project, especially as new team members modify the code without understanding the original constraint.
When to escalate
If you have applied the fix above and the symptom persists, the bug is likely in a different layer than this article addresses. Capture a video of the symptom, the exact reproduction steps, the Unreal Engine version, and any recent changes to the project. File a report on the official issue tracker with that bundle - the maintainers are responsive when the report is complete, and a well-reproduced issue often gets a workaround posted within a few days.
Before filing, search the existing issues for keywords related to your symptom. Many bug reports are duplicates of issues that have a workaround posted in the comments but no formal fix in the engine. Reading the existing thread often resolves the issue faster than a new report, and adding a +1 with your repro to an existing issue is more useful to the maintainers than another duplicate. For paid licenses (Unity Pro, Unreal Source Access), use the support portal for faster turnaround on engine-level bugs.
Check the boundary; the bug lives between systems.