zed-industries/zed · error
not supported
Error message
not supported
What it means
rewind() depends on connection.truncate(&self.session_id, cx) returning Some(truncate). When the connected agent does not implement session truncation, it returns None and rewind fails immediately with 'not supported'. This is a backend capability gap, not a data problem — restore_checkpoint is the git-backed alternative.
Source
Thrown at crates/acp_thread/src/acp_thread.rs:4024
git_store
.update(cx, |git, cx| git.restore_checkpoint(checkpoint, cx))
.await?;
}
Ok(())
})
}
/// Rewinds this thread to before the entry at `index`, removing it and all
/// subsequent entries while rejecting any action_log changes made from that point.
/// Unlike `restore_checkpoint`, this method does not restore from git.
pub fn rewind(
&mut self,
client_id: ClientUserMessageId,
cx: &mut Context<Self>,
) -> Task<Result<()>> {
let Some(truncate) = self.connection.truncate(&self.session_id, cx) else {
return Task::ready(Err(anyhow!("not supported")));
};
Self::flush_streaming_text(&mut self.streaming_text_buffer, cx);
let telemetry = ActionLogTelemetry::from(&*self);
cx.spawn(async move |this, cx| {
cx.update(|cx| truncate.run(client_id.clone(), cx)).await?;
this.update(cx, |this, cx| {
if let Some((ix, _)) = this.user_message_mut(&client_id) {
// Collect all terminals from entries that will be removed
let terminals_to_remove: Vec<acp::TerminalId> = this.entries[ix..]
.iter()
.flat_map(|entry| entry.terminals())
.filter_map(|terminal| terminal.read(cx).id().clone().into())
.collect();
let range = ix..this.entries.len();
this.entries.truncate(ix);
cx.emit(AcpThreadEvent::EntriesRemoved(range));View on GitHub (pinned to bc538def45)
Solutions
- Use restore_checkpoint instead — it rewinds entries and restores the git working tree
- Feature-check truncate support before showing the rewind affordance in the client
- Update the agent implementation to support session truncate
Defensive patterns
Strategy: type-guard
Validate before calling
// Feature-check truncate support before offering rewind
let supports_truncate = agent
.connection()
.truncate(&session_id, cx)
.is_some();
rewind_button.set_visible(supports_truncate); Type guard
fn connection_supports_rewind(agent: &Agent, session_id: &acp::SessionId, cx: &App) -> bool {
agent.connection().truncate(session_id, cx).is_some()
} Try / catch
let task = thread.update(cx, |thread, cx| thread.rewind(client_id.clone(), cx));
match task.await {
Err(error) if error.to_string().contains("not supported") => {
// Fall back to the git-backed path, which also rewinds entries.
return thread.update(cx, |thread, cx| {
thread.restore_checkpoint(client_id.clone(), cx)
}).await;
}
other => other?,
} Prevention
- Advertise rewind in the UI only when the connection implements truncate
- Keep restore_checkpoint as the user-visible fallback for agents without truncate
- Version-check external ACP agents for truncate support during onboarding
When it happens
Trigger: Calling rewind on a session whose ACP connection does not advertise/implement truncate: a third-party agent that never implemented session/truncate, or an agent speaking an older protocol version.
Common situations: Using Zed's agent panel against an external ACP agent lacking truncate support; version mismatch after updating one side; UI offers rewind because a checkpoint exists even though the connection cannot truncate.
Related errors
- output token limit reached
- message not found
- no thread found with ID: {id:?}
- Project state not found for session
- Session not found
AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16).
Data as JSON: /api/errors/de27cf4a0beba12e.
Report an issue: GitHub.