-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Claude Code provider drops user messages with agent_visible: false metadata #7930
Description
Bug Description
The Claude Code CLI provider silently drops user messages when they have agent_visible: false in their metadata, resulting in empty requests being sent to Claude. This causes the CLI to appear unresponsive while the desktop app works fine.
Root Cause
In crates/goose/src/providers/claude_code.rs, the last_user_content_blocks function at line 284 filters by is_agent_visible():
fn last_user_content_blocks(&self, messages: &[Message]) -> Vec<Value> {
let msgs = match messages.iter().rev().find(|m| m.role == Role::User) {
Some(msg) => std::slice::from_ref(msg),
None => messages,
};
let mut blocks: Vec<Value> = Vec::new();
for message in msgs.iter().filter(|m| m.is_agent_visible()) { // <-- BUG HERE
// ...
}
}Since msgs contains only the single last user message, if that message has agent_visible: false, the filter removes it entirely, resulting in empty content blocks being sent to Claude.
When Introduced
Commit 4abf91e72b on February 10, 2026 (PR #7108 "fix: isolate claude-code sessions via stream-json session_id")
The refactor changed from messages_to_content_blocks (which iterated all messages) to last_user_content_blocks (which finds only the last user message). The is_agent_visible() filter was incorrectly preserved from the original function.
Symptoms
- CLI appears to hang or not respond to user input
- Session shows
total_tokens: 0 - Desktop app works fine (uses
Message::user()with default metadata whereagent_visible: true) - No obvious error messages in logs
Proposed Fix
Remove the .filter(|m| m.is_agent_visible()) from line 284. The visibility filtering made sense when iterating over conversation history, but not when we've already specifically selected the user's message to send.
for message in msgs.iter() { // Remove the filterAffected Versions
v1.27.2 and likely all versions since February 10, 2026