{"record":{"id":"7edfe8448e456290","repo":"xpipe-io/xpipe","slug":"name-must-not-be-empty","errorCode":null,"errorMessage":"Name must not be empty","messagePattern":"Name must not be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/xpipe/app/util/StorePath.java","lineNumber":74,"sourceCode":"    }\n\n    /**\n     * Creates a new store path from a string representation.\n     *\n     * @param s the string representation, must be not null and fulfill certain requirements\n     * @throws IllegalArgumentException if the string is not valid\n     */\n    public static StorePath fromString(String s) {\n        if (s == null) {\n            throw new IllegalArgumentException(\"String is null\");\n        }\n\n        var split = s.split(String.valueOf(SEPARATOR), -1);\n\n        var names =\n                Arrays.stream(split).map(String::trim).map(String::toLowerCase).toList();\n        if (names.stream().anyMatch(s1 -> s1.isEmpty())) {\n            throw new IllegalArgumentException(\"Name must not be empty\");\n        }\n\n        return new StorePath(names);\n    }\n\n    @Override\n    public String toString() {\n        return names.stream().map(String::toLowerCase).collect(Collectors.joining(\"\" + SEPARATOR));\n    }\n}\n","sourceCodeStart":56,"sourceCodeEnd":85,"githubUrl":"https://github.com/xpipe-io/xpipe/blob/d85ca821baa46092a320ebb13546d7240adb74f8/app/src/main/java/io/xpipe/app/util/StorePath.java#L56-L85","documentation":"StorePath.fromString splits the input on the SEPARATOR character and trims/lowercases each segment. If any resulting segment is empty (e.g. leading/trailing separators or consecutive separators like \"a//b\" or \"/a\"), the parser throws this IllegalArgumentException because empty path names are not allowed.","triggerScenarios":"StorePath.fromString(\"\") (empty split yields one empty name), fromString(\"a//b\"), fromString(\"/leading\"), fromString(\"trailing/\"), or any segment that is only whitespace around separators.","commonSituations":"Hand-edited config files with stray separators; string concatenation that appends SEPARATOR unconditionally; copying a path with a trailing slash into the store path field.","solutions":["Strip leading/trailing separators before parsing: s.replaceAll(\"^\" + SEPARATOR + \"|\" + SEPARATOR + \"$\", \"\").","Pre-validate the string: Arrays.stream(s.split(SEPARATOR + \"\")).noneMatch(String::isBlank).","Fix whatever builds the string so empty segments are never emitted (e.g. String.join)."],"exampleFix":"// before\nStorePath p = StorePath.fromString(raw);\n// after\nString cleaned = raw.strip();\nwhile (cleaned.startsWith(String.valueOf(StorePath.SEPARATOR))) cleaned = cleaned.substring(1);\nwhile (cleaned.endsWith(String.valueOf(StorePath.SEPARATOR))) cleaned = cleaned.substring(0, cleaned.length() - 1);\nStorePath p = StorePath.fromString(cleaned);","handlingStrategy":"validation","validationCode":"public static boolean isWellFormedPath(String s) {\n    if (s == null) return false;\n    String[] parts = s.split(String.valueOf(StorePath.SEPARATOR));\n    return parts.length > 0 && Arrays.stream(parts).noneMatch(String::isBlank);\n}","typeGuard":null,"tryCatchPattern":"try {\n    StorePath p = StorePath.fromString(s);\n} catch (IllegalArgumentException e) {\n    // empty segment: leading/trailing/duplicate separator\n}","preventionTips":["Strip leading/trailing separators from user-entered paths","Build path strings with String.join instead of manual concatenation","Reject empty strings early in UI input fields"],"tags":["java","parsing","store-path","invalid-format"],"backgroundTag":"invalid-identifier-format","analyzedSha":"d85ca821baa46092a320ebb13546d7240adb74f8","analyzedAt":"2026-09-06T14:30:08.251Z","contentChangedAt":"2026-09-06T14:30:08.251Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}