can1357/oh-my-pi · error · TaskJobError

${message}${hint}

Error message

${message}${hint}

What it means

When a background Task job's execution fails with an unexpected error, the TaskTool wraps the original message in a TaskJobError and appends a follow-up hint (resumability/transcript info) if the agent is still registered. The thrown error text is `${message}${hint}` — the root-cause message plus guidance on how to follow up with the failed agent.

Source

Thrown at packages/coding-agent/src/task/index.ts:1223

					await reportProgress(statusText, buildDetails() as unknown as Record<string, unknown>);
					const deliveryText = `${finalText}${await buildFollowUpHint(singleResult?.aborted === true)}`;
					if (resultFailed) {
						// Mark the job itself failed; the failed agent stays interrogable.
						throw new TaskJobError(deliveryText);
					}
					return deliveryText;
				} catch (error) {
					if (error instanceof TaskJobError) {
						throw error;
					}
					progress.status = "failed";
					progress.durationMs = Math.max(0, Date.now() - startedAt);
					onSettled?.(true);
					const statusText = `Background task ${agentId} failed.`;
					await reportProgress(statusText, buildDetails() as unknown as Record<string, unknown>);
					const message = error instanceof Error ? error.message : String(error);
					const hint = AgentRegistry.global().get(agentId) ? await buildFollowUpHint(false) : "";
					throw new TaskJobError(`${message}${hint}`);
				} finally {
					releasePermit();
				}
			},
			{
				id: agentId,
				agentId,
				queued: true,
				ownerId: this.session.getAgentId?.() ?? undefined,
				onProgress: text => {
					onUpdate?.({ content: [{ type: "text", text }], details: buildDetails() });
				},
			},
		);
	}

	/**
	 * Sync fan-out (async unavailable, or every item's agent type is

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the message portion (before the hint) to identify the underlying failure and fix that root cause.
  2. If it was a transient API/network error, resume or re-run the task via the follow-up hint (hub message or history:// transcript).
  3. Check auth/model configuration if the message indicates provider/model errors.
  4. Catch TaskJobError in embedding code and inspect its message for the chained cause.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate the subagent's model/auth config before spawning the task
const agent = AgentRegistry.global().get(agentId);
if (!agent) throw new Error(`unknown agent ${agentId}`);
// ensure model credentials exist
const auth = await discoverAuthStorage();
if (!auth) console.warn("no auth storage; task likely to fail with provider error");

Try / catch

try {
  await runBackgroundTask(params);
} catch (err) {
  if (err instanceof TaskJobError) {
    // message = root cause + follow-up hint; split them for reporting
    const rootCause = err.message.split("\n\n")[0];
    logger.error("Background task failed", { rootCause });
  } else throw err;
}

Prevention

When it happens

Trigger: Any error thrown inside the registered job body other than TaskJobError itself (e.g. #executeSync failing on a provider error, config problem, or spawn crash) reaches the catch block; if AgentRegistry.global().get(agentId) finds the agent, buildFollowUpHint(false) text is appended and TaskJobError is thrown.

Common situations: Subagent run failing due to an invalid model, auth expiry, API/network error, or a tool-level failure — the underlying cause is in `message`; the hint tells you the agent is idle and resumable via hub/transcript.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/be54e28348f667de. Report an issue: GitHub.