{"record":{"id":"3bd2d749c42bdaa9","repo":"deepseek-ai/deepseek-harness","slug":"conversation-cancel-failed-result-error-code","errorCode":null,"errorMessage":"conversation.cancel failed: ${result.error.code}: ${result.error.message}","messagePattern":"conversation\\.cancel failed: (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/client/ui-conversation/src/client/service.ts","lineNumber":302,"sourceCode":"\n  /** Apply one operation to a pending queue occurrence. */\n  async updateQueue(itemId: QueueItemId, action: QueueAction): Promise<void> {\n    const session = this.scopedSession('updateQueue')\n    const result = await session.updateQueue(itemId, action)\n    if (!result.ok) {\n      if (\n        action.kind === 'steer'\n        && (result.error.code === 'steer-unavailable' || result.error.code === 'queue-item-not-found')\n      ) return\n      throw new Error(`conversation.updateQueue failed: ${result.error.code}: ${result.error.message}`)\n    }\n  }\n\n  /** Cancel the scoped session's in-flight turn while preserving Queue (failures land in promptError and reject, as in send). */\n  async cancel(): Promise<void> {\n    const session = this.scopedSession('cancel')\n    const result = await session.cancel()\n    if (!result.ok) throw new Error(`conversation.cancel failed: ${result.error.code}: ${result.error.message}`)\n  }\n\n  /** Pull one older history page for the scoped Session. */\n  async loadOlder(): Promise<void> {\n    await this.scopedSession('loadOlder').loadOlder()\n  }\n\n  /** Resolve the caller scope's session face or throw on root contexts. */\n  private scopedSession(op: string): SessionFace {\n    const id = this.scopeId(op)\n    const binding = this.requireSessions().binding(id)\n    if (binding === undefined) throw new Error(`conversation.${op}: session \"${id}\" resolved no binding`)\n    return binding.session\n  }\n\n  /** Read the caller's session scope tag via the sessions service; root contexts fail loud. */\n  private scopeId(op: string): SessionId {\n    const id = this.requireSessions().scopeOf(this.ctx)","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/ui-conversation/src/client/service.ts#L284-L320","documentation":"cancel() aborts the scoped session's in-flight turn via session.cancel while preserving the Queue. A non-ok result throws 'conversation.cancel failed: <code>: <message>' — most commonly because no turn is in flight anymore, so there is nothing to cancel.","triggerScenarios":"Clicking cancel after the turn already finished (host answers a no-active-turn style code); cancelling a session that was closed; transport failure during the cancel call.","commonSituations":"A Stop button racing natural turn completion; double-click on Stop; cancelling exactly as the connection drops.","solutions":["Treat no-active-turn codes as success — the goal (no running turn) already holds","Drive the Stop button's enabled state from the live frame so it is disabled when no turn is in flight","For transport codes, reconnect and re-check session state before retrying"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!turnInFlight(sessionSnapshot)) return // nothing to cancel","typeGuard":null,"tryCatchPattern":"try {\n  await conversation.cancel()\n} catch (error) {\n  if (isNoActiveTurn(error)) return // the goal already holds\n  throw error\n}","preventionTips":["Enable Stop only while a turn is in flight","Debounce the Stop button","On transport codes, resync session state before retrying"],"tags":["rpc","cancel","race-condition","session"],"backgroundTag":"rpc-request-failed","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}