#2797·inbox-zero

AI Assistant updateRule can clear rule AI instructions when aiInstructions and clearAiInstructions are both present

Author: JerrychenshenCreated Jun 7, 2026Updated Jun 14, 2026

Summary

The AI Assistant can accidentally clear a rule's AI instructions when updating the rule condition. I have seen this happen multiple times on a self-hosted Docker deployment. The affected rules were not deleted or disabled; only the Rule.instructions field was set to null, which made the rules appear as if their prompts disappeared.

Environment

  • Deployment: self-hosted Docker
  • Image: ghcr.io/elie222/inbox-zero:latest
  • Image revision: 694203b0a1aa85117d29e9877cb83b440b27eb45
  • Database: Postgres

What Happened

After using the AI Assistant to fix/rerun/update email classification rules, some rule AI instructions were cleared unexpectedly. In my case this happened to classification rules such as "FYI" and "Cold Email".

The rules still existed and their actions were still present, but the instructions field became empty/null.

Evidence

The related Assistant ChatMessage tool calls contained both a new instruction value and a clear flag in the same updateRule call:

json
{
  "condition": {
    "aiInstructions": "new instructions here",
    "clearAiInstructions": true
  }
}

Then RuleHistory showed versions where instructions became empty/null.

This appears to be caused by buildConditionUpdateData() in:

typescript
apps/web/utils/ai/assistant/tools/rules/update-rule-tool.ts

The current logic gives clearAiInstructions priority over aiInstructions:

typescript
if (condition.clearAiInstructions) {
  data.instructions = null;
} else if ("aiInstructions" in condition) {
  data.instructions = condition.aiInstructions;
}

So if the Assistant sends both fields, the new instructions are discarded and the rule is cleared.

Expected Behavior

If aiInstructions is present, the rule should be updated to those instructions.

clearAiInstructions should only clear the field when the Assistant/user explicitly intends to clear it and no replacement aiInstructions is provided.

Alternatively, the schema/tool should reject input that contains both aiInstructions and clearAiInstructions because the request is contradictory.

Actual Behavior

When both fields are present:

json
{
  "aiInstructions": "new instructions here",
  "clearAiInstructions": true
}

the rule instructions are cleared.

Possible Fix

One minimal defensive fix is to make aiInstructions win when it is present:

typescript
if ("aiInstructions" in condition) {
  data.instructions = condition.aiInstructions;
} else if (condition.clearAiInstructions) {
  data.instructions = null;
}

I also added a local regression test around updateRuleTool:

typescript
it("keeps new aiInstructions when clearAiInstructions is also present", async () => {
  // updateRuleTool receives both aiInstructions and clearAiInstructions
  // expected partial update data: { instructions: "Updated billing instructions." }
});

I could not run the test locally because pnpm was not installed in the environment, but the behavior matches the database evidence from the live deployment.

Question

Is the Assistant expected to ever send both aiInstructions and clearAiInstructions together? If not, should this be guarded at the schema/tool-call validation layer as well as in buildConditionUpdateData()?