chatboxai/chatbox · error · AgentModeRewardResumeError

The Agent Mode reward was claimed, but the interrupted task

Error message

The Agent Mode reward was claimed, but the interrupted task could not resume

What it means

Thrown by claimAgentModeRewardAndResume() as an AgentModeRewardResumeError when the reward claim and success display succeed but the subsequent resume() of the interrupted task fails. The error wraps the original resumeCause and preserves the claimed reward so the caller knows the reward was consumed even though the task did not resume — this is critical because the reward cannot be un-claimed.

Source

Thrown at src/renderer/packages/agent-mode-reward.ts:41

    this.name = 'AgentModeRewardResumeError'
  }
}

export async function claimAgentModeRewardAndResume({
  claim,
  showSuccess,
  resume,
}: {
  claim: () => Promise<ClaimedAgentModeReward>
  showSuccess: (reward: ClaimedAgentModeReward) => void
  resume: () => Promise<void>
}): Promise<ClaimedAgentModeReward> {
  const reward = await claim()
  showSuccess(reward)
  try {
    await resume()
  } catch (error) {
    throw new AgentModeRewardResumeError(reward, error)
  }
  return reward
}

View on GitHub (pinned to 81571269ad)

Solutions

  1. Catch AgentModeRewardResumeError specifically and inform the user the reward was claimed but the task needs manual restart.
  2. Persist the reward details (tokenLimit, expiresAt) locally so the user can restart the task manually within the validity window.
  3. Retry resume() with backoff for transient network failures before surfacing the error.

Example fix

// before
try {
  await resume()
} catch (error) {
  throw new AgentModeRewardResumeError(reward, error)
}

// caller — handle the partial-success state explicitly
try {
  await claimAgentModeRewardAndResume({ claim, showSuccess, resume })
} catch (e) {
  if (e instanceof AgentModeRewardResumeError) {
    toast.info(`Reward claimed, but the task could not resume: ${e.resumeCause}. Restart it manually.`)
    persistReward(e.reward)
  } else {
    throw e
  }
}
Defensive patterns

Strategy: try-catch

Type guard

import { AgentModeRewardResumeError } from './agent-mode-reward'
function isResumeError(e: unknown): e is AgentModeRewardResumeError {
  return e instanceof AgentModeRewardResumeError
}

Try / catch

try {
  await claimAgentModeRewardAndResume({ claim, showSuccess, resume })
} catch (error) {
  if (isResumeError(error)) {
    // Reward was claimed; task needs manual restart.
    persistRewardLocally(error.reward)
    toast.info('Reward claimed but the task could not resume. Restart it manually.')
  } else {
    throw error
  }
}

Prevention

When it happens

Trigger: claim() returns a reward, showSuccess() renders it, then resume() throws — e.g. the interrupted agent task's session was deleted, the network call to resume the task failed, or the task context expired. The wrapped error is attached as resumeCause.

Common situations: The interrupted task's session was removed while the reward modal was open; the resume endpoint is transiently unreachable; the task's state was garbage-collected after a long idle. Because the reward is already claimed server-side, the user faces a claimed-but-unusable state.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/fcff2517ecfe4855. Report an issue: GitHub.