Hmbown/CodeWhale · warning · std::io::Error
Session title cannot exceed {MAX_SESSION_TITLE_CHARS} charac
Error message
Session title cannot exceed {MAX_SESSION_TITLE_CHARS} characters What it means
normalize_session_title returns InvalidInput when a title exceeds MAX_SESSION_TITLE_CHARS (100), counted in characters (not bytes) after sanitization and trimming. Like the empty-title check, it applies uniformly to the picker, /rename, and PATCH /v1/sessions/{id}.
Source
Thrown at crates/tui/src/session_manager.rs:1917
.collect()
}
/// Sanitize, trim, and bound a user-supplied session title.
///
/// Returns `InvalidInput` for an empty title or one longer than
/// [`MAX_SESSION_TITLE_CHARS`] so every rename surface (picker, `/rename`,
/// `PATCH /v1/sessions/{id}`) rejects the same inputs with the same reason.
pub fn normalize_session_title(title: &str) -> std::io::Result<String> {
let sanitized = sanitize_session_title(title);
let trimmed = sanitized.trim();
if trimmed.is_empty() {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Session title cannot be empty",
));
}
if trimmed.chars().count() > MAX_SESSION_TITLE_CHARS {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Session title cannot exceed {MAX_SESSION_TITLE_CHARS} characters"),
));
}
Ok(trimmed.to_string())
}
pub(crate) fn workspace_scope_matches(saved_workspace: &Path, current_workspace: &Path) -> bool {
if paths_equivalent(saved_workspace, current_workspace) {
return true;
}
// Repository identity comes from the containing checkout itself (Git
// dir/worktree traversal shared with project-context scope resolution),
// never from branch names or paths mentioned in conversation.
let canonical = |path: &Path| fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf());
match (
find_git_root(&canonical(saved_workspace)),View on GitHub (pinned to 0c42157ee5)
Solutions
- Shorten the title to 100 characters or fewer (count characters, not bytes)
- Truncate client-side before the rename call if auto-generating titles: title.chars().take(100).collect()
- Prefer a concise human title; store longer context elsewhere, not in the title field
Example fix
// before
let title = normalize_session_title(&auto_generated_500_char_summary)?; // InvalidInput
after:
let title = normalize_session_title(
&auto_generated_500_char_summary.chars().take(100).collect::<String>(),
)?; Defensive patterns
Strategy: validation
Validate before calling
const LIMIT: usize = codewhale_tui::session_manager::MAX_SESSION_TITLE_CHARS; // 100
let candidate = sanitize_session_title(raw).trim();
if candidate.chars().count() > LIMIT {
candidate = candidate.chars().take(LIMIT).collect::<String>();
} Type guard
fn is_title_too_long(e: &std::io::Error) -> bool {
e.kind() == std::io::ErrorKind::Input
&& e.to_string().contains("cannot exceed")
} Prevention
- Count chars(), not len() bytes — CJK/emoji titles hit byte limits early and pass char limits
- Cap auto-generated titles at 100 chars at the generation site
- Show a live character counter in rename UIs
When it happens
Trigger: Any rename call with a sanitized, trimmed title longer than 100 chars — e.g. auto-generated titles from a file path or transcript summary, or pasted multi-line text collapsed into one long string.
Common situations: Clients that derive titles from filenames/branch names without a length cap; CJK titles where callers assumed a byte limit; multi-paste concatenation producing one giant string.
Related errors
- Session title cannot be empty
- tmux has-session for {session} failed with {}: {}
- continual harness entry id cannot be empty
- install source must not be empty
- legacy spillover ownership requires a session id
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/a0381437c8f52c0e.
Report an issue: GitHub.