{"record":{"id":"bee83339cdbfaa8e","repo":"languagetool-org/languagetool","slug":"ngramlangidentdata-does-not-exist-or-is-a-director","errorCode":null,"errorMessage":"ngramLangIdentData does not exist or is a directory (needs to be a ZIP file): ","messagePattern":"ngramLangIdentData does not exist or is a directory \\(needs to be a ZIP file\\): ","errorType":"console","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java","lineNumber":516,"sourceCode":"          String key = (String)o;\n          if (!KNOWN_OPTION_KEYS.contains(key) && !key.matches(\"lang-[a-z]+-dictPath\") && !key.matches(\"lang-[a-z]+\")) {\n            System.err.println(\"***** WARNING: ****\");\n            System.err.println(\"Key '\" + key + \"' from configuration file '\" + file + \"' is unknown. Please check the key's spelling (case is significant).\");\n            System.err.println(\"Known keys: \" + KNOWN_OPTION_KEYS);\n          }\n        }\n\n        addDynamicLanguages(props);\n        setAbTest(getOptionalProperty(props, \"abTest\", null));\n        setAbTestClients(getOptionalProperty(props, \"abTestClients\", null));\n        setAbTestRollout(Integer.parseInt(getOptionalProperty(props, \"abTestRollout\", \"100\")));\n        String ngramLangIdentData = getOptionalProperty(props, \"ngramLangIdentData\", null);\n        setDefaultThirdPartyAI(Boolean.parseBoolean(getOptionalProperty(props, \"defaultThirdPartyAI\", \"false\")));\n\n        if (ngramLangIdentData != null) {\n          File dir = new File(ngramLangIdentData);\n          if (!dir.exists() || dir.isDirectory()) {\n            throw new IllegalArgumentException(\"ngramLangIdentData does not exist or is a directory (needs to be a ZIP file): \" + ngramLangIdentData);\n          }\n          setNgramLangIdentData(dir);\n        }\n      }\n    } catch (IOException e) {\n      throw new RuntimeException(\"Could not load properties from '\" + file + \"'\", e);\n    }\n  }\n\n  private void addDynamicLanguages(Properties props) throws IOException {\n    for (Object keyObj : props.keySet()) {\n      String key = (String)keyObj;\n      if (key.startsWith(\"lang-\") && !key.contains(\"-dictPath\")) {\n        String code = key.substring(\"lang-\".length());\n        if (!code.contains(\"-\") && code.length() != 2 && code.length() != 3) {\n          throw new IllegalArgumentException(\"code is supposed to be a 2 (or rarely 3) character code (unless it uses a format with variant, like xx-YY): '\" + code + \"'\");\n        }\n        String nameKey = \"lang-\" + code;","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java#L498-L534","documentation":"The 'ngramLangIdentData' property must point to an existing ZIP file containing n-gram language-identification data. If the path does not exist or is a directory, HTTPServerConfig throws this IllegalArgumentException at startup.","triggerScenarios":"Server properties contains 'ngramLangIdentData=/path' where the path is missing, or points to a directory instead of the expected ZIP file (e.g. extracted archives).","commonSituations":"Operator downloaded and unzipped the language-ident data and pointed the config at the extracted folder; file not copied to the container; wrong filename.","solutions":["Point 'ngramLangIdentData' at the ZIP file itself (not the extracted directory)","Download the ngram language-ident data package if it is missing","Remove the 'ngramLangIdentData' property if this feature is not needed"],"exampleFix":"// before (server.properties)\nngramLangIdentData=/opt/languagetool/ngrams/\n\n// after (server.properties)\nngramLangIdentData=/opt/languagetool/ngrams/langident.zip","handlingStrategy":"validation","validationCode":"String p = props.getProperty(\"ngramLangIdentData\");\nif (p != null) {\n    File f = new File(p);\n    if (!f.exists() || f.isDirectory()) throw new IllegalStateException(\"ngramLangIdentData must be an existing ZIP file: \" + p);\n}","typeGuard":null,"tryCatchPattern":"try {\n    serverConfig = new HTTPServerConfig(props);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"ngramLangIdentData does not exist\")) {\n        log.error(\"Point ngramLangIdentData at the ZIP file, not a directory: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Point the property at the .zip archive, never the extracted folder","Verify with 'file <path>' that it is a zip before starting the server","Remove the property if ngram language identification is not used"],"tags":["java","languagetool","file-not-found","server-config"],"backgroundTag":"file-not-found","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}