moeru-ai/airi · warning

Dropped spark:notify after max attempts:

Error message

Dropped spark:notify after max attempts:

What it means

The character orchestrator queues spark:notify events with a retry schedule (attempts + computeNextRunAt backoff). When processSparkNotify throws and the event has already consumed its max attempts, the event is dropped permanently and this warning records the last error. Dropped means the mod's proactive trigger for that tick will never fire — it is data loss for that single notify, bounded by design.

Source

Thrown at packages/stage-ui/src/stores/character/orchestrator/store.ts:238

      return

    const [next] = scheduledNotifies.value.splice(nextIndex, 1)
    removePending(next.event.data.id)

    try {
      await processSparkNotify(next.event, next.control)
    }
    catch (error) {
      if (next.attempts + 1 < next.maxAttempts) {
        scheduledNotifies.value = [...scheduledNotifies.value, {
          ...next,
          attempts: next.attempts + 1,
          nextRunAt: computeNextRunAt(next.event, next.attempts + 1),
        }]
        pendingNotifies.value = [...pendingNotifies.value, next.event]
      }
      else {
        console.warn('Dropped spark:notify after max attempts:', error)
      }
    }
  }

  function startTicker() {
    if (tickTimer)
      return

    tickTimer = setInterval(() => {
      void tick()
    }, attentionConfig.value.tickIntervalMs)
  }

  function stopTicker() {
    if (!tickTimer)
      return

    clearInterval(tickTimer)

View on GitHub (pinned to 677329427f)

Solutions

  1. Read the logged error object — it is the underlying cause from processSparkNotify, not the drop itself.
  2. Fix the failing mod handler (schema mismatch, missing dependency) in the mod source.
  3. If the cause is a transient provider outage, no action: future spark events will process normally.
  4. Increase maxAttempts/backoff only if outages longer than the window are expected and stale notifies are still valuable.
Defensive patterns

Strategy: retry

Try / catch

try {
  await processSparkNotify(next.event, next.control)
}
catch (error) {
  if (next.attempts + 1 < next.maxAttempts) {
    // re-queue with backoff (existing behavior)
  }
  else {
    // log and drop; surface to mod developer tooling if attached
  }
}

Prevention

When it happens

Trigger: processSparkNotify (which typically invokes mod logic/LLM calls for the notification) keeps failing across all scheduled retries — e.g. the mod throws on the event payload, a downstream provider keeps erroring, or a spark condition references missing state.

Common situations: A mod's spark handler has a bug triggered by a specific payload shape; LLM/provider outage lasting longer than the retry window; mod updated to an incompatible event schema; per-event failure that is payload-dependent so every retry fails identically.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/fe7fb3d2c8788973. Report an issue: GitHub.