Skip to content

Conversation

Copy link

Copilot AI commented Nov 18, 2025

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

Bug: File state is lost when multiple file operations are performed

Problem Description

When tools that update files (like write_file or edit_file) are called, the new state in "files" only contains the most recently edited file. All other previously existing files disappear from the state.

Root Cause

The issue is in the wrapToolCall function in src/middleware/fs.ts (around lines 476-510). When accumulating file updates from multiple tool calls, the function only considers the updates from the current Command but doesn't preserve the existing state.

Specifically, this line:

const accumulatedFiles: Record<string, FileData> = {
  ...(update.files || {}),
};

Only spreads update.files (which might be empty or only contain the current update), but never includes the existing files from request.state.files.

Expected Behavior

When a file is written or edited:

  1. The modified file should be updated in the state
  2. All other existing files should remain in the state
  3. The fileDataReducer should properly merge the updates with the existing state

Solution

The accumulatedFiles initialization should include the current state:

const accumulatedFiles: Record<string, FileData | null> = {
  ...(request.state?.files || {}),  // Include existing files from state
  ...(update.files || {}),
};

Alternatively, the fileDataReducer should be called manually when processing file updates:

let accumulatedFiles = request.state?.files || {};

for (const msg of update.messages) {
  if (msg instanceof ToolMessage) {
    const processed = await processToolMessage(msg);
    processedMessages.push(processed.message);

    if (processed.filesUpdate) {
      hasLargeResults = true;
      // Manually call the reducer to properly merge updates
      accumulatedFiles = fileDataReducer(accumulatedFiles, processed.filesUpdate);
    }
  } else {
    processedMessages.push(msg);
  }
}

Impact

This bug causes significant data loss - all files except the most recently modified one disappear from the state after each file operation, making it impossible to maintain a proper filesystem state across multiple operations.

This pull request was created as a result of the following prompt from Copilot chat.

Bug: File state is lost when multiple file operations are performed

Problem Description

When tools that update files (like write_file or edit_file) are called, the new state in "files" only contains the most recently edited file. All other previously existing files disappear from the state.

Root Cause

The issue is in the wrapToolCall function in src/middleware/fs.ts (around lines 476-510). When accumulating file updates from multiple tool calls, the function only considers the updates from the current Command but doesn't preserve the existing state.

Specifically, this line:

const accumulatedFiles: Record<string, FileData> = {
  ...(update.files || {}),
};

Only spreads update.files (which might be empty or only contain the current update), but never includes the existing files from request.state.files.

Expected Behavior

When a file is written or edited:

  1. The modified file should be updated in the state
  2. All other existing files should remain in the state
  3. The fileDataReducer should properly merge the updates with the existing state

Solution

The accumulatedFiles initialization should include the current state:

const accumulatedFiles: Record<string, FileData | null> = {
  ...(request.state?.files || {}),  // Include existing files from state
  ...(update.files || {}),
};

Alternatively, the fileDataReducer should be called manually when processing file updates:

let accumulatedFiles = request.state?.files || {};

for (const msg of update.messages) {
  if (msg instanceof ToolMessage) {
    const processed = await processToolMessage(msg);
    processedMessages.push(processed.message);

    if (processed.filesUpdate) {
      hasLargeResults = true;
      // Manually call the reducer to properly merge updates
      accumulatedFiles = fileDataReducer(accumulatedFiles, processed.filesUpdate);
    }
  } else {
    processedMessages.push(msg);
  }
}

Impact

This bug causes significant data loss - all files except the most recently modified one disappear from the state after each file operation, making it impossible to maintain a proper filesystem state across multiple operations.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@janpawellek
Copy link

Sorry, I tried to create this PR using Copilot, but it failed due to insufficient permissions. Now I can't even modify or close it.

I manually created a PR at #63 instead.
Please close this PR in favor of #63. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants