can1357/oh-my-pi · error · ToolError

Apply failed: ${message}

Error message

Apply failed: ${message}

What it means

runResolveInvocation applies a staged resolution (approve/apply of a pending action). When the underlying apply throws a non-ToolError exception, it rethrows as ToolError('Apply failed: <message>') so the tool layer surfaces a consistent error. The optional onApplyError/requeue hook is invoked first but its own failure is swallowed.

Source

Thrown at packages/coding-agent/src/tools/resolve.ts:262

	const baseDetails: ResolveDetails = {
		action: params.action,
		reason: params.reason,
		sourceToolName: options.sourceToolName,
		label: options.label,
	};
	if (params.action === "apply") {
		let result: AgentToolResult<unknown>;
		try {
			result = await options.apply(params.reason);
		} catch (error) {
			try {
				options.onApplyError?.(error);
			} catch {
				// Requeue hook must not mask the original apply failure.
			}
			if (error instanceof ToolError) throw error;
			const message = error instanceof Error ? error.message : String(error);
			throw new ToolError(`Apply failed: ${message}`);
		}
		return {
			...result,
			details: {
				...baseDetails,
				...(result.details != null ? { sourceResultDetails: result.details } : {}),
			},
		};
	}
	if (options.reject != null) {
		const result = await options.reject(params.reason);
		if (result != null) {
			return {
				...result,
				details: {
					...baseDetails,
					...(result.details != null ? { sourceResultDetails: result.details } : {}),
				},

View on GitHub (pinned to 9690622007)

Solutions

  1. Read the embedded message after 'Apply failed: ' to find the root cause
  2. Re-check the target files for changes and re-run the plan/preview to stage a fresh action
  3. Fix filesystem permissions or free disk space if the message indicates EACCES/ENOSPC
  4. Retry the resolve once the underlying cause is fixed
Defensive patterns

Strategy: try-catch

Validate before calling

// before applying, confirm the staged target still matches
current = await Bun.file(targetPath).text();
if (current !== previewedContent) throw new Error("File changed since preview; re-stage");

Try / catch

try { await resolveApply(); } catch (e) { if (e instanceof ToolError && e.message.startsWith("Apply failed:")) { logger.warn("resolve apply failed", { cause: e.message.slice("Apply failed: ".length) }); /* re-stage and retry */ } else throw e; }

Prevention

When it happens

Trigger: The apply path (patch application, file write, hook execution) throws a generic Error — e.g. patch context mismatch, filesystem permission denied, or an internal exception that is not a ToolError.

Common situations: Staged edit no longer matches the file (file changed since preview); read-only working tree; disk full; a plugin/hook corrupted state.

Related errors


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