Hmbown/CodeWhale · warning · std::io::Error
Session title cannot be empty
Error message
Session title cannot be empty
What it means
normalize_session_title returns InvalidInput when a session title is empty after sanitize_session_title and trim. Every rename surface (the session picker, the /rename command, and PATCH /v1/sessions/{id}) funnels through this one function, so all of them reject the same input with the same message.
Source
Thrown at crates/tui/src/session_manager.rs:1911
/// OSC 0 terminal title, `codewhale sessions` stdout, and the picker, so the
/// persisted value must not be able to carry a raw escape sequence. Ordinary
/// text, punctuation, CJK, and emoji pass through untouched.
pub fn sanitize_session_title(raw: &str) -> String {
raw.chars()
.filter(|ch| !ch.is_control() && !is_title_format_char(*ch))
.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;
}
View on GitHub (pinned to 0c42157ee5)
Solutions
- Send a title containing at least one printable, non-control character
- If you control the caller, run trim (and the same sanitization) before submitting so you can give the user a better message than the server error
- Check where the empty string comes from — often a template variable or unset field defaulting to blank
Example fix
// before
let title = normalize_session_title(" \u{0}")?; // InvalidInput
// after
let cleaned = sanitize_session_title(raw).trim().to_string();
if cleaned.is_empty() {
return Ok(fallback_title()); // or prompt the user again
}
let title = normalize_session_title(&cleaned)?; Defensive patterns
Strategy: validation
Validate before calling
let candidate = sanitize_session_title(raw).trim();
if candidate.is_empty() {
// reject in the UI/form before calling any rename API
return Err(own_error("title is required"));
} Type guard
fn is_empty_title_error(e: &std::io::Error) -> bool {
e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("cannot be empty")
} Try / catch
match normalize_session_title(&raw) {
Ok(t) => rename(id, &t).await,
Err(e) if is_empty_title_error(&e) => show_field_error("title", "Enter a non-empty title"),
Err(e) => show_field_error("title", &e.to_string()),
} Prevention
- Validate after sanitize+trim, not on the raw string — sanitization can empty a non-empty input
- Use HTML/UI required-field checks so users never submit blank titles
- Default auto-generated titles to a real value (e.g. first words of the transcript) instead of blank
When it happens
Trigger: Calling a rename API with a title of "", whitespace-only input, or a title made entirely of characters the sanitizer strips (control characters, zero-width characters), so nothing printable remains after sanitize+trim.
Common situations: A web/API client submits a form with whitespace only; caller validates length before sanitization and misses that sanitization empties the string; double-trim or templating bug produces an empty default title.
Related errors
- Session title cannot exceed {MAX_SESSION_TITLE_CHARS} charac
- tmux has-session for {session} failed with {}: {}
- Automation name cannot be empty
- Automation prompt cannot be empty
- Trigger message must not be empty
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/c88103c7d8509979.
Report an issue: GitHub.