{"record":{"id":"a0381437c8f52c0e","repo":"Hmbown/CodeWhale","slug":"session-title-cannot-exceed-max-session-title-cha","errorCode":null,"errorMessage":"Session title cannot exceed {MAX_SESSION_TITLE_CHARS} characters","messagePattern":"Session title cannot exceed (.+?) characters","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"warning","filePath":"crates/tui/src/session_manager.rs","lineNumber":1917,"sourceCode":"        .collect()\n}\n\n/// Sanitize, trim, and bound a user-supplied session title.\n///\n/// Returns `InvalidInput` for an empty title or one longer than\n/// [`MAX_SESSION_TITLE_CHARS`] so every rename surface (picker, `/rename`,\n/// `PATCH /v1/sessions/{id}`) rejects the same inputs with the same reason.\npub fn normalize_session_title(title: &str) -> std::io::Result<String> {\n    let sanitized = sanitize_session_title(title);\n    let trimmed = sanitized.trim();\n    if trimmed.is_empty() {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            \"Session title cannot be empty\",\n        ));\n    }\n    if trimmed.chars().count() > MAX_SESSION_TITLE_CHARS {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            format!(\"Session title cannot exceed {MAX_SESSION_TITLE_CHARS} characters\"),\n        ));\n    }\n    Ok(trimmed.to_string())\n}\n\npub(crate) fn workspace_scope_matches(saved_workspace: &Path, current_workspace: &Path) -> bool {\n    if paths_equivalent(saved_workspace, current_workspace) {\n        return true;\n    }\n\n    // Repository identity comes from the containing checkout itself (Git\n    // dir/worktree traversal shared with project-context scope resolution),\n    // never from branch names or paths mentioned in conversation.\n    let canonical = |path: &Path| fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf());\n    match (\n        find_git_root(&canonical(saved_workspace)),","sourceCodeStart":1899,"sourceCodeEnd":1935,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/session_manager.rs#L1899-L1935","documentation":"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}.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet title = normalize_session_title(&auto_generated_500_char_summary)?; // InvalidInput\n\nafter:\nlet title = normalize_session_title(\n    &auto_generated_500_char_summary.chars().take(100).collect::<String>(),\n)?;","handlingStrategy":"validation","validationCode":"const LIMIT: usize = codewhale_tui::session_manager::MAX_SESSION_TITLE_CHARS; // 100\nlet candidate = sanitize_session_title(raw).trim();\nif candidate.chars().count() > LIMIT {\n    candidate = candidate.chars().take(LIMIT).collect::<String>();\n}","typeGuard":"fn is_title_too_long(e: &std::io::Error) -> bool {\n    e.kind() == std::io::ErrorKind::Input\n        && e.to_string().contains(\"cannot exceed\")\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["input-validation","session","rename","rust","length-limit"],"backgroundTag":"string-length-limit","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}