remix-run/remix · warning
render called after component was removed, potential applica
Error message
render called after component was removed, potential application memory leak
What it means
The UI component runtime warns when render() is invoked on a component that was already removed from the tree. This usually indicates a retained reference to a removed component whose render is still being scheduled, which leaks memory and does work that is discarded.
Source
Thrown at packages/ui/src/runtime/component.ts:298
#scheduleUpdate = (): void => {
let queue = this.#updateQueue
if (!queue) throw new Error('scheduleUpdate not implemented')
let vnode = this.#updateVNode
let domParent = this.#updateDomParent
if (!vnode || !domParent) throw new Error('scheduleUpdate target not initialized')
queue.enqueue(vnode, domParent)
}
#tasks: Task[] = []
constructor(config: ComponentConfig) {
this.#config = config
this.frame = config.frame
this.#handle = this.#createHandle()
}
render = (nextProps: ElementProps): [RemixNode, Array<() => void>] => {
if (this.#removed) {
console.warn('render called after component was removed, potential application memory leak')
return [null, []]
}
this.#abortRenderSignal()
syncProps(this.#props, nextProps)
let renderFn = this.#renderFn
if (renderFn === undefined) {
let initialize = this.#config.type as unknown as (handle: Handle<ElementProps, C>) => unknown
let result = initialize(this.#handle)
if (!isRenderFn(result)) {
let name = this.#config.type.name || 'Anonymous'
throw new Error(`${name} must return a render function, received ${typeof result}`)
}
renderFn = resultView on GitHub (pinned to 9696913134)
Solutions
- Cancel pending render schedules in the component's cleanup/unmount path
- Audit subscriptions and timers that capture the component and close over it after removal
- Return early when the component's owning region is unmounted
Example fix
// before
const interval = setInterval(() => component.render(props), 1000)
// after
const interval = setInterval(() => { if (!removed) component.render(props) }, 1000)
clearInterval(interval) // on cleanup Defensive patterns
Strategy: validation
Validate before calling
if (!component.isRemoved?.()) component.render(props)
Prevention
- Clear timers/subscriptions that capture component handles on unmount
- Cancel pending scheduler callbacks in cleanup paths
When it happens
Trigger: Holding onto a component runtime handle (or a stale scheduler callback) after the component unmounted, then calling render(nextProps) on it.
Common situations: Missing cleanup in effects/subscriptions that capture the component; scheduler queues not flushed or cancelled on unmount; hydration regions replaced while queued renders remain.
Related errors
- popover.surface() requires a registered anchor before openin
- Duplicate keys detected in siblings: ${quotedKeys.join(', ')
- ${cascadingComponentUpdateCount} cascading component updates
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/3249622668680ab0.
Report an issue: GitHub.