dapr/dapr · error
timers are not implemented
Error message
timers are not implemented
What it means
The workflow executor internal actor implements InvokeTimer by returning errors.New("timers are not implemented") (executor.go:325-327). Executor actors have no timer lifecycle: workflow timers are durable timers managed by the orchestrator via reminders. The error fires only if a timer is delivered to an executor actor, which means a timer was scheduled against an internal actor type or a misrouted scheduler entry.
Source
Thrown at pkg/actors/targets/workflow/executor/executor.go:326
}
// tryDeactivate requests deactivation without ever blocking the caller: the
// deactivation queue is drained serially and each item waits on the actor's
// wait group, which the caller is currently holding. If the queue is full the
// actor simply stays in the table until HaltNonHosted or shutdown reaps it.
func (e *executor) tryDeactivate() {
select {
case e.deactivateCh <- e:
default:
}
}
func (e *executor) InvokeReminder(ctx context.Context, reminder *actorapi.Reminder) error {
return errors.New("reminders are not implemented")
}
func (e *executor) InvokeTimer(ctx context.Context, reminder *actorapi.Reminder) error {
return errors.New("timers are not implemented")
}
func (e *executor) Deactivate(_ context.Context) error {
if !e.closed.CompareAndSwap(false, true) {
return nil
}
// Close under mu so complete's closed-check-then-park cannot straddle
// the close and strand a payload in a deactivated actor. wg.Wait stays
// outside: in-flight invocations hold wg and may be waiting on mu.
e.mu.Lock()
close(e.closeCh)
e.table.Delete(e.actorID)
e.mu.Unlock()
e.wg.Wait()
return nil
}
View on GitHub (pinned to 74ad417027)
Solutions
- Remove timers scheduled on dapr internal workflow actor types
- Register timers only on your application actors
- Purge scheduler entries that target internal actor types after upgrades
- Align daprd versions so internal actor naming stays consistent
Defensive patterns
Strategy: validation
Validate before calling
// before registering a timer, ensure the target is an application actor
if isInternalWorkflowActor(actorType) {
return errors.New("timers cannot target internal workflow actors")
} Type guard
func isTimerNotImplemented(err error) bool {
return err != nil && strings.Contains(err.Error(), "timers are not implemented")
} Try / catch
if err := scheduler.RegisterTimer(ctx, actorType, id, t); err != nil {
if isTimerNotImplemented(err) {
return fmt.Errorf("timer routed to internal actor %q: target an app actor instead", actorType)
}
return err
} Prevention
- Register timers only on application actor types
- Use workflow APIs (durable timers) for time-based workflow logic, not actor timers
- Audit scheduler entries after runtime upgrades
When it happens
Trigger: CreateTimer/scheduler timer delivery addressed to the workflow executor actor type; tooling that registers timers on every actor type including internal ones; scheduler state replay after upgrades.
Common situations: Enumerating actor types and scheduling timers programmatically; leftover scheduler entries from an older runtime; custom tooling driving internal actor APIs.
Related errors
- reminders are not implemented
- timers are not implemented
- unknown method: %s
- invalid timer object for creating a timer reminder
- cross-app purge does not support force without recursive
AI-assisted analysis of dapr/dapr@74ad417027 (2026-08-16).
Data as JSON: /api/errors/a9bce568e9f1e54f.
Report an issue: GitHub.