coleam00/Archon · error

file_change_failed_no_changes

file_change_failed_no_changes

Error message

❌ File change failed: ${fileErrorMessage}

What it means

While streaming Codex events, a file-change item reports a failed status with no changes applied. streamCodexEvents emits a user-facing '❌ File change failed' system message, including any underlying fileErrorMessage when the harness provided one (code file_change_failed_no_changes).

Source

Thrown at packages/providers/src/codex/provider.ts:723

                return `${icon} ${c.path ?? '(unknown file)'}`;
              })
              .join('\n');
            const errorSuffix =
              (item.status as string) === 'failed' && fileErrorMessage
                ? `\n${fileErrorMessage}`
                : '';
            yield {
              type: 'system',
              content: `${statusIcon} File changes:\n${changeList}${errorSuffix}`,
            };
          } else if ((item.status as string) === 'failed') {
            getLog().warn(
              { itemId: item.id, status: item.status },
              'file_change_failed_no_changes'
            );
            const failMsg = fileErrorMessage
              ? `❌ File change failed: ${fileErrorMessage}`
              : '❌ File change failed';
            yield { type: 'system', content: failMsg };
          } else {
            getLog().debug({ itemId: item.id, status: item.status }, 'file_change_no_changes');
          }
          break;
        }

        case 'mcp_tool_call': {
          const server = item.server as string | undefined;
          const tool = item.tool as string | undefined;
          const mcpToolName = getMcpToolName(item);

          if ((item.status as string) === 'failed') {
            getLog().warn(
              { server, tool, error: item.error, itemId: item.id },
              'mcp_tool_call_failed'
            );
            const mcpError = item.error as { message?: string } | undefined;

View on GitHub (pinned to 0773b97458)

Solutions

  1. Read the accompanying fileErrorMessage for the concrete cause and fix it (e.g. resolve the conflicting file state).
  2. Re-run the workflow turn after the file conflict is resolved.
  3. Check workspace permissions/paths if the failure is an access error; retry the change manually.

Example fix

// before
// turn re-reads stale file, patch fails, no changes applied
// ❌ File change failed: patch does not apply
// after
git checkout -- path/to/file   # restore known state, rerun the turn
// file change applied
Defensive patterns

Strategy: try-catch

Validate before calling

// before applying, ensure target files are clean and writable
const status = await git(['status', '--porcelain', targetPath]);
if (status.trim()) console.warn(`${targetPath} has local changes; agent patch may fail`);

Try / catch

for await (const ev of streamCodexEvents(...)) {
  if (ev.type === 'system' && ev.content.startsWith('❌ File change failed')) {
    // capture ev.content (includes fileErrorMessage) and abort/retry the turn
    break;
  }
}

Prevention

When it happens

Trigger: A Codex turn's file-change item ends with a failed status — e.g. the proposed edit could not be applied (conflict, read-only file, path outside workspace) and no changes were written.

Common situations: Editing a file that changed on disk since the agent read it; applying a patch to a protected or read-only path; diff context drift after earlier failed edits in the same turn.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/532f3e945f5ef8fd. Report an issue: GitHub.