{"record":{"id":"5b890c95e3c855fe","repo":"facebook/flow","slug":"only-7bit-ascii-allowed-in","errorCode":null,"errorMessage":"only 7bit ascii allowed in {}","messagePattern":"only 7bit ascii allowed in (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_lsp/src/file_url.rs","lineNumber":59,"sourceCode":"        Err(err)\n    } else if cfg!(windows) {\n        Ok(s.replace('/', \"\\\\\"))\n    } else {\n        Ok(s)\n    }\n}\n\nfn encode(safe_chars: &str, s: &str) -> String {\n    let mut buf = String::with_capacity(s.len() * 2);\n    for c in s.chars() {\n        if cfg!(windows) && c == '\\\\' {\n            buf.push('/');\n        } else if safe_chars.contains(c) {\n            buf.push(c);\n        } else {\n            let code = c as u32;\n            if !(32..=127).contains(&code) {\n                panic!(\"only 7bit ascii allowed in {}\", s);\n            }\n            buf.push_str(&format!(\"%{code:02X}\"));\n        }\n    }\n    buf\n}\n\npub fn parse(uri: &str) -> Result<String, String> {\n    let caps = URL_RE\n        .captures(uri)\n        .ok_or_else(|| format!(\"not a file url - {}\", uri))?;\n    let host = caps.get(1).unwrap().as_str();\n    let path = caps.get(2).unwrap().as_str();\n    let query_fragment = caps.get(3).unwrap().as_str();\n    let path = decode(path)?;\n    if !host.is_empty() && host != \"localhost\" {\n        return Err(format!(\"not localhost - {}\", uri));\n    }","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_lsp/src/file_url.rs#L41-L77","documentation":"flow_lsp::file_url::create() converts a filesystem path into a file:// URI by percent-encoding every character not in PATH_SAFE_CHARS. encode() can only emit %XX escapes for code points in printable 7-bit ASCII (32..=127); any other character — an accented letter, CJK character, emoji, or a control char — hits this panic. So merely opening a document whose absolute path contains non-ASCII text crashes the conversion instead of producing a URI.","triggerScenarios":"Calling file_url::create(path) (directly or through LSP document-open flows) with a path containing any character outside 32..=127: /users/jose/, /home/user/projeto-文档/, emoji in folder names, or control characters in a filename. Windows backslashes are fine (they are converted to '/'); only non-ASCII code points trigger it.","commonSituations":"Machines with localized usernames (e.g. /Users/josé/); projects checked out into non-ASCII directories; files copied from other OSes keeping Unicode names; CI caches rooted under Unicode paths; tests with Unicode fixtures.","solutions":["Move (or symlink) the project to an all-ASCII path and reopen it from there — this is the immediate workaround.","Ensure TMPDIR/HOME and the workspace root are ASCII-only, since derived paths inherit them.","Fix encode() upstream to percent-encode the raw UTF-8 BYTES of each non-ASCII char (RFC 3986) instead of panicking: iterate s.as_bytes() and emit %XX per byte, since code points >= 128 are exactly what the range check rejects today.","Decode side note: parse()/decode() has the same 7-bit restriction, so keep the fix symmetric if you patch both."],"exampleFix":"// before (flow_lsp/src/file_url.rs)\nlet code = c as u32;\nif !(32..=127).contains(&code) {\n    panic!(\"only 7bit ascii allowed in {}\", s);\n}\nbuf.push_str(&format!(\"%{code:02X}\"));\n\n// after: percent-encode raw UTF-8 bytes, RFC 3986 style\nfor b in c.to_string().as_bytes() {\n    buf.push_str(&format!(\"%{b:02X}\"));\n}","handlingStrategy":"validation","validationCode":"// before file_url::create(path)\nif !path.is_ascii() {\n    return Err(format!(\"path contains non-ASCII characters unsupported by file_url: {path}\"));\n}\nlet uri = file_url::create(path);","typeGuard":"fn is_ascii_path(p: &str) -> bool {\n    p.is_ascii()\n}","tryCatchPattern":"let uri = std::panic::catch_unwind(|| file_url::create(path));\nmatch uri {\n    Ok(u) => Ok(u),\n    Err(_) => Err(\"file_url only supports 7-bit ASCII paths; relocate the file\".into()),\n}","preventionTips":["Keep workspace and temp paths ASCII-only, especially home directories with localized usernames.","In CI, set TMPDIR/HOME to ASCII paths.","Patch encode() locally to percent-encode UTF-8 bytes per RFC 3986 instead of code points.","Add a test fixture with a Unicode filename so regressions surface before users do."],"tags":["lsp","file-url","unicode","percent-encoding","paths","i18n"],"backgroundTag":"uri-percent-encoding","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}