MCPcopy
hub / github.com/coder/mux / failAgentTaskTerminally

Method failAgentTaskTerminally

src/node/services/taskService.ts:8504–8584  ·  view source on GitHub ↗

* Terminal settlement for a child task whose stream failed with a * non-retryable error: mark interrupted with a descriptive launch error, * persist a durable failure artifact in every ancestor session dir (so * background children, restarts, and post-cleanup task_awaits observe the * ty

(
    workspaceId: string,
    entry: { projectPath: string; workspace: WorkspaceConfigEntry },
    failure: { errorType: string; errorMessage: string }
  )

Source from the content-addressed store, hash-verified

8502 * typed failure), then reject pending waiters with the failure message.
8503 */
8504 private async failAgentTaskTerminally(
8505 workspaceId: string,
8506 entry: { projectPath: string; workspace: WorkspaceConfigEntry },
8507 failure: { errorType: string; errorMessage: string }
8508 ): Promise<void> {
8509 assert(workspaceId.length > 0, "failAgentTaskTerminally: workspaceId must be non-empty");
8510 assert(
8511 failure.errorMessage.length > 0,
8512 "failAgentTaskTerminally: errorMessage must be non-empty"
8513 );
8514
8515 await this.editWorkspaceEntry(
8516 workspaceId,
8517 (ws) => {
8518 ws.taskStatus = "interrupted";
8519 ws.taskLaunchError = failure.errorMessage;
8520 },
8521 { allowMissing: true }
8522 );
8523 await this.emitWorkspaceMetadata(workspaceId);
8524
8525 const parentWorkspaceId = entry.workspace.parentWorkspaceId;
8526 if (parentWorkspaceId) {
8527 const cfg = this.config.loadConfigOrDefault();
8528 const index = this.buildAgentTaskIndex(cfg);
8529 const ancestorWorkspaceIds = this.listAncestorWorkspaceIdsUsingParentById(
8530 index.parentById,
8531 workspaceId
8532 );
8533 const workflowOwnedAncestorWorkspaceIds = ancestorWorkspaceIds.filter(
8534 (ancestorWorkspaceId) =>
8535 this.getWorkflowOwnedDescendantAgentTaskUsingIndex(
8536 index,
8537 ancestorWorkspaceId,
8538 workspaceId
8539 ) === true
8540 );
8541
8542 const persistedAtMs = Date.now();
8543 for (const ancestorWorkspaceId of ancestorWorkspaceIds) {
8544 try {
8545 await upsertSubagentFailureArtifact({
8546 workspaceId: ancestorWorkspaceId,
8547 workspaceSessionDir: this.config.getSessionDir(ancestorWorkspaceId),
8548 childTaskId: workspaceId,
8549 parentWorkspaceId,
8550 ancestorWorkspaceIds,
8551 workflowOwnedAncestorWorkspaceIds,
8552 errorType: failure.errorType,
8553 errorMessage: failure.errorMessage,
8554 model: entry.workspace.taskModelString,
8555 nowMs: persistedAtMs,
8556 });
8557 } catch (error: unknown) {
8558 log.error("Failed to persist subagent failure artifact", {
8559 workspaceId: ancestorWorkspaceId,
8560 childTaskId: workspaceId,
8561 error,

Tested by

no test coverage detected