{"record":{"id":"f92a8df835630589","repo":"elastic/elasticsearch","slug":"empty-geohash","errorCode":null,"errorMessage":"empty geohash","messagePattern":"empty geohash","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/geo/src/main/java/org/elasticsearch/geometry/utils/Geohash.java","lineNumber":324,"sourceCode":"        long b;\n        long l = 0L;\n        for (char c : hash.toCharArray()) {\n            b = (long) (BASE_32_STRING.indexOf(c));\n            l |= (b << (level-- * 5));\n            if (level < 0) {\n                // We cannot handle more than 12 levels\n                break;\n            }\n        }\n        return (l << 4) | length;\n    }\n\n    /**\n     * Encode to a morton long value from a given geohash string\n     */\n    public static long mortonEncode(final String hash) {\n        if (hash.isEmpty()) {\n            throw new IllegalArgumentException(\"empty geohash\");\n        }\n        int level = 11;\n        long b;\n        long l = 0L;\n        for (char c : hash.toCharArray()) {\n            b = (long) (BASE_32_STRING.indexOf(c));\n            if (b < 0) {\n                throw new IllegalArgumentException(\"unsupported symbol [\" + c + \"] in geohash [\" + hash + \"]\");\n            }\n            l |= (b << ((level-- * 5) + (MORTON_OFFSET - 2)));\n            if (level < 0) {\n                // We cannot handle more than 12 levels\n                break;\n            }\n        }\n        return BitUtil.flipFlop(l);\n    }\n","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/geo/src/main/java/org/elasticsearch/geometry/utils/Geohash.java#L306-L342","documentation":"Thrown by Geohash.mortonEncode(String) when the input geohash string is empty. An empty geohash encodes no spatial information, so the method rejects it immediately rather than returning a default morton code. The check runs before any character processing.","triggerScenarios":"Calling `Geohash.mortonEncode(\"\")`, or any higher-level API that delegates to it (Geohash.toPoint, Geohash.toBoundingBox) with an empty string.","commonSituations":"Missing/blank geohash field in source documents; string trimming that reduced a whitespace value to empty; null-coalescing that turned null into \"\" instead of rejecting; upstream filter that allowed empty strings through.","solutions":["Filter out empty/null geohashes before calling mortonEncode or its dependents.","Treat empty geohash as missing data and skip the record (or use a sentinel/default location).","Validate the input string is non-empty after trimming at the ingestion boundary."],"exampleFix":"// before\nlong m = Geohash.mortonEncode(hash); // throws if hash.isEmpty()\n\n// after\nif (hash == null || hash.isBlank()) {\n    return; // or handle as missing\n}\nlong m = Geohash.mortonEncode(hash);","handlingStrategy":"validation","validationCode":"if (hash == null || hash.isEmpty()) {\n    throw new IllegalArgumentException(\"geohash missing\"); // or skip the record\n}\nreturn Geohash.mortonEncode(hash);","typeGuard":"static boolean isNonEmptyGeohash(String hash) {\n    return hash != null && !hash.isEmpty();\n}","tryCatchPattern":null,"preventionTips":["Treat null and empty geohash as missing data at ingestion.","Validate non-empty after trimming at the trust boundary.","Do not coalesce null to \"\" — skip the record instead."],"tags":["geometry","geohash","validation","empty-input","libs-geo"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}