{"record":{"id":"8328a4b99a6a68b6","repo":"gitui-org/gitui","slug":"invalid-path","errorCode":null,"errorMessage":"invalid path.","messagePattern":"invalid path\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/components/status_tree.rs","lineNumber":178,"sourceCode":"\t) -> Option<Span<'b>> {\n\t\tlet indent_str = if indent == 0 {\n\t\t\tString::new()\n\t\t} else {\n\t\t\tformat!(\"{:w$}\", \" \", w = indent * 2)\n\t\t};\n\n\t\tif !visible {\n\t\t\treturn None;\n\t\t}\n\n\t\tmatch file_item_kind {\n\t\t\tFileTreeItemKind::File(status_item) => {\n\t\t\t\tlet status_char =\n\t\t\t\t\tSelf::item_status_char(status_item.status);\n\t\t\t\tlet file = Path::new(&status_item.path)\n\t\t\t\t\t.file_name()\n\t\t\t\t\t.and_then(std::ffi::OsStr::to_str)\n\t\t\t\t\t.expect(\"invalid path.\");\n\n\t\t\t\tlet txt = if selected {\n\t\t\t\t\tformat!(\n\t\t\t\t\t\t\"{} {}{:w$}\",\n\t\t\t\t\t\tstatus_char,\n\t\t\t\t\t\tindent_str,\n\t\t\t\t\t\tfile,\n\t\t\t\t\t\tw = width as usize\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tformat!(\"{status_char} {indent_str}{file}\")\n\t\t\t\t};\n\n\t\t\t\tSome(Span::styled(\n\t\t\t\t\tCow::from(txt),\n\t\t\t\t\ttheme.item(status_item.status, selected),\n\t\t\t\t))\n\t\t\t}","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/gitui-org/gitui/blob/2fa693cb6ed431b21ebc300dd02e83c2476699ce/src/components/status_tree.rs#L160-L196","documentation":"While rendering the status tree, gitui takes each changed file's path and extracts its final component via Path::file_name(), then converts it with OsStr::to_str(). file_name() returns None for degenerate paths that end in a parent component (e.g. '..' or a root), and to_str() returns None when the bytes are not valid UTF-8; either case trips this expect() and panics the render path, crashing the UI.","triggerScenarios":"A filename in the git status output containing non-UTF-8 bytes (media files with legacy latin-1/Shift-JIS names, archives extracted on other systems); a degenerate path ending in '..' produced by renames or tooling.","commonSituations":"Repos with legacy encoded filenames; files created by Windows/macOS tools with unusual encodings; untracked files with byte sequences invalid in UTF-8 appearing in the status view.","solutions":["Find the offender: git -c core.quotepath=false status --porcelain | LC_ALL=C grep -n '[^ -~]' to spot non-ASCII/broken names.","Rename the offending file to valid UTF-8 (git mv for tracked files) or remove it from the working tree.","Update gitui - path handling in the status tree was hardened in later releases; report the panic trace with the path bytes if it reproduces on a current build."],"exampleFix":"// before\nlet file = Path::new(&status_item.path)\n    .file_name()\n    .and_then(std::ffi::OsStr::to_str)\n    .expect(\"invalid path.\");\n// after: degrade instead of panicking\nlet file = Path::new(&status_item.path)\n    .file_name()\n    .and_then(std::ffi::OsStr::to_str)\n    .unwrap_or(\"(invalid path)\");","handlingStrategy":"validation","validationCode":"# repo hygiene check before opening the status view\ngit -c core.quotepath=false status --porcelain | LC_ALL=C grep -n '[^ -~]'\n# any output line is a candidate crash trigger\n\n// Rust: pre-check each path before rendering\nPath::new(&p).file_name().and_then(std::ffi::OsStr::to_str).is_some()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep repo filenames UTF-8; rename legacy-encoded names when adopting TUI tools.","Run the porcelain grep above whenever gitui inexplicably panics on the status screen.","In your own TUI rendering, use unwrap_or placeholders instead of expect() on path conversions."],"tags":["panic","non-utf8","file-path","status-tree","rendering"],"backgroundTag":"non-utf8-file-path","analyzedSha":"2fa693cb6ed431b21ebc300dd02e83c2476699ce","analyzedAt":"2026-08-16T23:07:36.562Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}