{"record":{"id":"19c75bbceb29dc98","repo":"OpenHands/OpenHands","slug":"conversation-conversationid-was-not-found","errorCode":null,"errorMessage":"Conversation ${conversationId} was not found","messagePattern":"Conversation (.+?) was not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/api/conversation-service/agent-server-conversation-service.api.ts","lineNumber":317,"sourceCode":"  \"error\",\n  \"stuck\",\n]);\n\nfunction toRuntimeStatus(\n  status: DirectConversationInfo[\"execution_status\"],\n): RuntimeConversationInfo[\"status\"] {\n  const nextStatus = status ?? \"idle\";\n  return (\n    RUNTIME_STATUSES.has(nextStatus) ? nextStatus : \"idle\"\n  ) as RuntimeConversationInfo[\"status\"];\n}\n\nfunction requireAppConversation(\n  conversation: AppConversation | null | undefined,\n  conversationId: string,\n): AppConversation {\n  if (!conversation) {\n    throw new Error(`Conversation ${conversationId} was not found`);\n  }\n  return conversation;\n}\n\n/**\n * Options for {@link AgentServerConversationService.createConversation}.\n */\nexport interface CreateConversationOptions {\n  initialUserMsg?: string;\n  conversationInstructions?: string;\n  plugins?: PluginSpec[];\n  metadata?: ConversationMetadata | null;\n  workingDirOverride?: string;\n  workspaceMode?: WorkspaceMode;\n  parentConversationId?: string;\n  agentType?: \"default\" | \"plan\";\n  sandboxId?: string;\n  // Launch from a saved AgentProfile (resolved server-side) instead of the","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/OpenHands/OpenHands/blob/500b4c533e9393e44cb92894bcbb18438ef473b6/src/api/conversation-service/agent-server-conversation-service.api.ts#L299-L335","documentation":"Thrown by requireAppConversation when a batchGetAppConversations call for a specific conversation ID returns null/undefined for that entry. This is a defensive guard in methods like updateConversationTitle and updateConversationRepository that fetch the conversation after mutating it, expecting it to exist. The error includes the conversationId in the message.","triggerScenarios":"updateConversationTitle or updateConversationRepository is called with a conversationId that doesn't exist on the agent-server. The mutation (title update or metadata write) may succeed locally, but the subsequent batchGetAppConversations lookup returns null because the server doesn't have that conversation.","commonSituations":"Conversation was deleted by another session or tab between the title edit and the fetch; the conversationId in the URL is stale (from a bookmarked link to a deleted conversation); the agent-server was reset/reinstalled losing conversation state; a cloud-to-local backend switch caused the conversation to not exist on the new backend.","solutions":["Verify the conversation still exists before calling update methods: const [conv] = await batchGetAppConversations([id]); if (!conv) return;","Handle the not-found case gracefully in the UI by redirecting to the home page.","Check if the user switched backends, which would invalidate conversation IDs."],"exampleFix":"// before\nconst updated = await AgentServerConversationService.updateConversationTitle(id, title);\n\n// after: handle not-found\ntry {\n  const updated = await AgentServerConversationService.updateConversationTitle(id, title);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('was not found')) {\n    navigate('/'); // redirect to home\n    return;\n  }\n  throw e;\n}","handlingStrategy":"validation","validationCode":"async function conversationExists(id: string): Promise<boolean> {\n  const [conv] = await AgentServerConversationService.batchGetAppConversations([id]);\n  return conv != null;\n}\n\n// Before title/repository update:\nif (!(await conversationExists(id))) {\n  navigate('/'); // redirect to home\n  return;\n}","typeGuard":"function isConversationNotFound(e: unknown): boolean {\n  return e instanceof Error && /was not found/.test(e.message);\n}","tryCatchPattern":"try {\n  await AgentServerConversationService.updateConversationTitle(id, title);\n} catch (error) {\n  if (error instanceof Error && error.message.includes('was not found')) {\n    navigate('/');\n    return;\n  }\n  throw error;\n}","preventionTips":["Verify conversation existence after backend switches — IDs are backend-specific.","Handle 404/not-found errors by redirecting to home rather than leaving a broken chat view.","Invalidate React Query conversation caches when the backend changes."],"tags":["conversation","not-found","data-integrity","backend-switch"],"backgroundTag":null,"analyzedSha":"500b4c533e9393e44cb92894bcbb18438ef473b6","analyzedAt":"2026-08-12T10:07:46.034Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}