Hmbown/CodeWhale · error
AutomationEditorConflict
Error message
AutomationEditorConflict
What it means
AutomationEditor::save performs optimistic-concurrency detection: it re-reads the latest stored automation record and compares every field the save request touches (schedule/rrule, cwds, model, status) against the original record the editor loaded. If any differ, someone else modified the automation and it bails with the AutomationEditorConflict message instead of clobbering their changes.
Solutions
- Reload the automation in the editor (discard or merge your edits with the latest record) and re-apply changes, then save again.
- If the concurrent change is unwanted, revert the record to the original state first, then save.
- Retry the save immediately after reload if contention is rare and changes are trivial.
Defensive patterns
Strategy: try-catch
Try / catch
match editor.save() {
Err(e) if e.to_string().contains("conflict") => { editor.reload_latest(); prompt_user_to_reapply(); }
other => other?,
} Prevention
- Reload the record immediately before saving when possible to shrink the race window.
- Avoid leaving the editor open long; edit and save promptly.
- Coordinate edits to the same automation across windows/agents.
- Expect conflicts on automations whose status changes automatically (pauses, runs).
When it happens
Trigger: Calling save with request fields Some(...) where latest.rrule != original.rrule, latest.cwds != original.cwds, ModelChoice::from_record(&latest) != ModelChoice::from_record(original), or latest.status != original.status — i.e. the stored record changed under the editor.
Common situations: Another window/agent edited or paused the same automation while the editor was open; an automated job status transition happened between open and save; a schedule sync tool updated the record.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- AutomationEditorInvalidWorkspace
- An existing Fleet artifact contains different bytes
- bundle contains conflicting or rejected entries
- destination already exists with different content
- Fleet task selects member whose role is , but worker.role…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/13b68670fd6951b8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/views/automations/editor.rs:684
cwds: workspace_changed.then_some(cwds),
model: (choice != ModelChoice::from_record(original))
.then(|| choice.model.clone().unwrap_or_default()),
model_provider: (choice != ModelChoice::from_record(original))
.then(|| choice.provider.clone().unwrap_or_default()),
model_provider_id: (choice != ModelChoice::from_record(original))
.then(|| choice.provider_id.clone().unwrap_or_default()),
status: (status != original.status).then_some(status),
..Default::default()
};
if (request.name.is_some() && latest.name != original.name)
|| (request.prompt.is_some() && latest.prompt != original.prompt)
|| (request.rrule.is_some() && latest.rrule != original.rrule)
|| (request.cwds.is_some() && latest.cwds != original.cwds)
|| (request.model.is_some()
&& ModelChoice::from_record(&latest) != ModelChoice::from_record(original))
|| (request.status.is_some() && latest.status != original.status)
{
anyhow::bail!("{}", tr(self.locale, MessageId::AutomationEditorConflict));
}
manager.update_automation(&original.id, request)
} else {
manager.create_automation(CreateAutomationRequest {
name: self.name.value.clone(),
prompt: self.prompt.value.clone(),
rrule,
cwds,
model: choice.model,
model_provider: choice.provider,
model_provider_id: choice.provider_id,
status: Some(status),
mode: None,
allow_shell: None,
trust_mode: None,
auto_approve: None,
delivery_mode: None,
})View on GitHub (pinned to 73e0f67d83)