{"record":{"id":"c68d1d07071c32ba","repo":"astral-sh/ruff","slug":"invalidinput","errorCode":"InvalidInput","errorMessage":"Input is not a text document: {path}","messagePattern":"Input is not a text document: (.+?)","errorType":"error_code","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/ty_server/src/system.rs","lineNumber":340,"sourceCode":"struct UntrustedWorkspaceExecutor;\n\nimpl CommandExecutor for UntrustedWorkspaceExecutor {\n    fn execute(&self, _command: Command) -> Result<Output> {\n        Err(std::io::Error::new(\n            std::io::ErrorKind::PermissionDenied,\n            \"external commands are disabled in an untrusted workspace\",\n        ))\n    }\n\n    fn dyn_clone(&self) -> Box<dyn CommandExecutor> {\n        Box::new(Self)\n    }\n}\n\nfn not_a_text_document(path: impl Display) -> std::io::Error {\n    std::io::Error::new(\n        std::io::ErrorKind::InvalidInput,\n        format!(\"Input is not a text document: {path}\"),\n    )\n}\n\nfn virtual_path_not_found(path: impl Display) -> std::io::Error {\n    std::io::Error::new(\n        std::io::ErrorKind::NotFound,\n        format!(\"Virtual path does not exist: {path}\"),\n    )\n}\n\n/// Helper function to get the [`FileRevision`] of the given document.\nfn document_revision(document: &Document, index: &Index) -> FileRevision {\n    // The file revision is just an opaque number which doesn't have any significant meaning other\n    // than that the file has changed if the revisions are different.\n    #[expect(clippy::cast_sign_loss)]\n    match document {\n        Document::Text(text) => FileRevision::new(text.version() as u128),\n        Document::Notebook(notebook) => {","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ty_server/src/system.rs#L322-L358","documentation":"The ty server resolves virtual paths (untitled documents, notebook cells) through the LSP document index. read_virtual_path_to_string looks the path up and requires the stored Document to be a text document; if it is a Notebook document it returns ErrorKind::InvalidInput with 'Input is not a text document: {path}'.","triggerScenarios":"A string-oriented read hits a virtual path whose open LSP document is a NotebookDocument instead of a TextDocument - e.g. notebook cell paths read via read_to_string while the editor syncs that document as a notebook.","commonSituations":"Editors that sync Jupyter files as NotebookDocuments (VS Code Jupyter) while a code path assumes plain text; notebook-document support toggling between ty versions; stale assumptions about how a path is synced.","solutions":["Use notebook-aware reads (read_to_notebook) for notebook documents instead of read_to_string","Inspect the document kind in the index before choosing the read API","Ensure the client's notebookDocument capabilities match how the documents are actually synced"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before reading a virtual path, confirm the synced document kind matches the read API\nlet expected_text = matches!(index.document_for(path), Some(Document::Text(_)));\nif !expected_text { use_notebook_read_instead(); }","typeGuard":"fn is_text_document(doc: &Document) -> bool { matches!(doc, Document::Text(_)) }","tryCatchPattern":"match system.read_virtual_path_to_string(path) {\n    Ok(s) => { /* use s */ }\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => { /* re-read as notebook or skip */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep notebook and text reads paired with the corresponding document kind","Advertise notebookDocument capabilities consistently in the client","Log the document kind alongside virtual-path read failures"],"tags":["lsp","notebook","virtual-path","io","type-mismatch"],"backgroundTag":"invalid-input-type-mismatch","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}