{"record":{"id":"e121896e414ce64e","repo":"helix-editor/helix","slug":"directory-is-empty-did-you-use-hx-grammar","errorCode":null,"errorMessage":"Directory {:?} is empty. Did you use 'hx --grammar fetch'?","messagePattern":"Directory (.+?) is empty\\. Did you use 'hx --grammar fetch'\\?","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"helix-loader/src/grammar.rs","lineNumber":522,"sourceCode":"        PathBuf::from(&path)\n    } else {\n        crate::runtime_dirs()\n            .first()\n            .expect(\"No runtime directories provided\") // guaranteed by post-condition\n            .join(\"grammars\")\n            .join(\"sources\")\n            .join(&grammar.grammar_id)\n    };\n\n    let grammar_dir_entries = grammar_dir.read_dir().with_context(|| {\n        format!(\n            \"Failed to read directory {:?}. Did you use 'hx --grammar fetch'?\",\n            grammar_dir\n        )\n    })?;\n\n    if grammar_dir_entries.count() == 0 {\n        return Err(anyhow!(\n            \"Directory {:?} is empty. Did you use 'hx --grammar fetch'?\",\n            grammar_dir\n        ));\n    };\n\n    let path = match &grammar.source {\n        GrammarSource::Git {\n            subpath: Some(subpath),\n            ..\n        } => grammar_dir.join(subpath),\n        _ => grammar_dir,\n    }\n    .join(\"src\");\n\n    build_tree_sitter_library(&path, grammar, target)\n}\n\nfn build_tree_sitter_library(","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/helix-editor/helix/blob/079a789e8cb08ead67f19e1971a1b7438b37354b/helix-loader/src/grammar.rs#L504-L540","documentation":"Raised while building tree-sitter grammars when the grammar's source directory under runtime/grammars/sources/<grammar_id> exists but contains zero entries. The fetch step populates these directories; an empty one means the grammar was never fetched or a previous fetch/clone silently produced nothing.","triggerScenarios":"Running 'hx --grammar build' on a fresh checkout or after clearing the runtime grammar dir without ever running 'hx --grammar fetch'; a partial fetch interrupted after creating the directory but before cloning; runtime/grammars/sources manually emptied.","commonSituations":"New install where the user skipped the fetch step; distro packaging that ships empty grammar dirs; CI cache that preserves directories but not contents; a grammar added by a languages.toml override whose source was never fetched.","solutions":["Run 'hx --grammar fetch' first, then 'hx --grammar build'","If fetch was already run, verify the directory shown in the error actually has content and disk isn't full / dirs aren't permission-restricted","For a grammar added via a custom languages.toml entry, ensure its repository URL is reachable during fetch"],"exampleFix":"# before\nhx --grammar build   # -> Directory ... is empty. Did you use 'hx --grammar fetch'?\n\n# after\nhx --grammar fetch && hx --grammar build","handlingStrategy":"validation","validationCode":"// Before building, verify the grammar sources dir is populated:\nfn grammar_sources_present(rt: &Path, id: &str) -> bool {\n    std::fs::read_dir(rt.join(\"grammars\").join(\"sources\").join(id))\n        .map(|mut d| d.next().is_some())\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair fetch with build: 'hx --grammar fetch && hx --grammar build'","Don't partially clean runtime/grammars/sources; clear it fully then re-fetch","In CI/Dockerfiles, do the fetch+build layer once and cache it"],"tags":["rust","helix","grammar","tree-sitter","build"],"backgroundTag":null,"analyzedSha":"079a789e8cb08ead67f19e1971a1b7438b37354b","analyzedAt":"2026-08-16T09:09:59.668Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}