{"record":{"id":"f175bb6f9403fc83","repo":"risingwavelabs/risingwave","slug":"task-not-found-f175bb","errorCode":null,"errorMessage":"Task not found","messagePattern":"Task not found","errorType":"error_code","errorClass":"ErrorCode","httpStatus":null,"severity":"warning","filePath":"src/frontend/src/error.rs","lineNumber":149,"sourceCode":"        #[backtrace]\n        CastError,\n    ),\n    #[error(\"Catalog error: {0}\")]\n    CatalogError(\n        #[source]\n        #[backtrace]\n        #[message]\n        BoxedError,\n    ),\n    #[error(\"Protocol error: {0}\")]\n    ProtocolError(#[message] String),\n    #[error(\"Scheduler error: {0}\")]\n    SchedulerError(\n        #[source]\n        #[backtrace]\n        BoxedError,\n    ),\n    #[error(\"Task not found\")]\n    TaskNotFound,\n    #[error(\"Session not found\")]\n    SessionNotFound,\n    #[error(\"Invalid reference: {0}\")]\n    InvalidReference(String),\n    #[error(\"Item not found: {0}\")]\n    ItemNotFound(String),\n    #[error(\"Duplicate Relation Name: {0}\")]\n    DuplicateRelationName(String),\n    #[error(\"Invalid insert operation: {0}\")]\n    InsertViolation(String),\n    #[error(\"Invalid input syntax: {0}\")]\n    InvalidInputSyntax(#[message] String),\n    #[error(\"Cannot compare in memory: {0}\")]\n    MemComparableError(#[from] memcomparable::Error),\n    #[error(\"Error while de/se values: {0}\")]\n    ValueEncodingError(\n        #[from]","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/error.rs#L131-L167","documentation":"RisingWave frontend's ErrorCode::TaskNotFound unit variant, rendered as \"Task not found\". It is returned when an operation references a query/batch task (e.g. canceling or querying its status) that the frontend no longer tracks — it never existed, already completed, or was purged.","triggerScenarios":"Canceling a batch query whose task ID is no longer registered with the frontend; polling status of a finished/expired task; racing between task completion and a cancel request.","commonSituations":"Client cancels a query just as it finishes; a load balancer routes a cancel to a different frontend node than the one holding the task; stale task IDs cached by an application after restart.","solutions":["Treat it as benign if the goal was cancellation — the task is already gone/finished.","Re-submit the operation against a task ID obtained from the same frontend node that owns the task.","Ensure cancel/status RPCs for a session's tasks go to the same frontend (sticky routing).","Check whether the frontend restarted, discarding in-memory task state."],"exampleFix":"// before\nawait client.cancel(taskId) // throws if already finished\n// after\ntry { await client.cancel(taskId) } catch (e) { if (isTaskNotFound(e)) return; throw e; }","handlingStrategy":"try-catch","validationCode":"// before cancel\nconst live = await listRunningTasks(); if (!live.includes(taskId)) return 'already-finished';","typeGuard":null,"tryCatchPattern":"try { await cancel(taskId) } catch (e) {\n  if (/Task not found/.test(e.message)) return 'already finished';\n  throw e;\n}","preventionTips":["Treat cancel-on-finished as a no-op in client code.","Use sticky routing so task operations hit the owning frontend node.","Never cache task IDs across frontend restarts."],"tags":["task","risingwave","scheduler","race-condition"],"backgroundTag":"record-not-found","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}