{"record":{"id":"793dddbba0e65082","repo":"GraphiteEditor/Graphite","slug":"failed-to-parse-document","errorCode":null,"errorMessage":"Failed to parse document","messagePattern":"Failed to parse document","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"node-graph/graph-craft/src/util.rs","lineNumber":6,"sourceCode":"use crate::document::NodeNetwork;\nuse crate::graphene_compiler::Compiler;\nuse crate::proto::ProtoNetwork;\n\npub fn load_network(document_string: &str) -> NodeNetwork {\n\tlet document: serde_json::Value = serde_json::from_str(document_string).expect(\"Failed to parse document\");\n\tlet document = (document[\"network_interface\"][\"network\"].clone()).to_string();\n\tserde_json::from_str::<NodeNetwork>(&document).expect(\"Failed to parse document\")\n}\n\npub fn compile(network: NodeNetwork) -> ProtoNetwork {\n\tlet compiler = Compiler {};\n\tcompiler.compile_single(network).unwrap()\n}\n\npub fn load_from_name(name: &str) -> NodeNetwork {\n\tlet content = std::fs::read(format!(\"../../demo-artwork/{name}.graphite\")).expect(\"failed to read file\");\n\tlet content = std::str::from_utf8(&content).unwrap();\n\tload_network(content)\n}\n\npub static DEMO_ART: [&str; 7] = [\n\t\"changing-seasons\",\n\t\"painted-dreams\",","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/node-graph/graph-craft/src/util.rs#L1-L24","documentation":"graph-craft's load_network parses the raw .graphite document text with serde_json; this first from_str fails when the content is not valid JSON at all. The file was read successfully, but its bytes do not form a JSON document.","triggerScenarios":"load_from_name reading a truncated or corrupted ../../demo-artwork/*.graphite file; a name resolving to a path containing non-JSON content; a download that saved an HTML error page with a .graphite extension.","commonSituations":"Incomplete LFS checkouts in CI; hand-editing documents and breaking JSON syntax; UTF-16 or BOM-prefixed exports from other tools.","solutions":["Validate the file with jq or any JSON linter before passing it in","Parse via serde_json::from_str::<serde_json::Value> (or serde_path_to_error) first to get a precise position message","Re-export the artwork from the editor to regenerate clean JSON"],"exampleFix":"// before\nlet document: serde_json::Value = serde_json::from_str(document_string).expect(\"Failed to parse document\");\n\n// after\nlet document: serde_json::Value = serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_str(document_string))\n\t.unwrap_or_else(|e| panic!(\"Failed to parse document at {}: {e}\", e.path()));","handlingStrategy":"validation","validationCode":"fn is_valid_json(text: &str) -> bool {\n\tserde_json::from_str::<serde_json::Value>(text).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match serde_json::from_str::<serde_json::Value>(document_string) {\n\tOk(v) => v,\n\tErr(e) => return Err(format!(\"document is not valid JSON: {e}\")),\n}","preventionTips":["Run jq or an equivalent JSON validation over shared artwork files in CI","Save files atomically (write to temp then rename) to avoid truncated documents","Prefer round-tripping saves through the editor rather than hand-editing JSON"],"tags":["serde-json","document","file-io","graphite"],"backgroundTag":"json-parse-failed","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}