{"record":{"id":"c7cfe4772b0d1e46","repo":"apache/flink","slug":"orphaned-minus-sign","errorCode":null,"errorMessage":"Orphaned minus sign.","messagePattern":"Orphaned minus sign\\.","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/types/parser/ByteParser.java","lineNumber":129,"sourceCode":"     * @param delimiter The delimiter that terminates the field.\n     * @return The parsed value.\n     * @throws NumberFormatException Thrown when the value cannot be parsed because the text\n     *     represents not a correct number.\n     */\n    public static final byte parseField(byte[] bytes, int startPos, int length, char delimiter) {\n        long val = 0;\n        boolean neg = false;\n\n        if (bytes[startPos] == delimiter) {\n            throw new NumberFormatException(\"Empty field.\");\n        }\n\n        if (bytes[startPos] == '-') {\n            neg = true;\n            startPos++;\n            length--;\n            if (length == 0 || bytes[startPos] == delimiter) {\n                throw new NumberFormatException(\"Orphaned minus sign.\");\n            }\n        }\n\n        for (; length > 0; startPos++, length--) {\n            if (bytes[startPos] == delimiter) {\n                return (byte) (neg ? -val : val);\n            }\n            if (bytes[startPos] < 48 || bytes[startPos] > 57) {\n                throw new NumberFormatException(\"Invalid character.\");\n            }\n            val *= 10;\n            val += bytes[startPos] - 48;\n\n            if (val > Byte.MAX_VALUE && (!neg || val > -Byte.MIN_VALUE)) {\n                throw new NumberFormatException(\"Value overflow/underflow\");\n            }\n        }\n        return (byte) (neg ? -val : val);","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/types/parser/ByteParser.java#L111-L147","documentation":"Thrown by ByteParser.parseField when a field consists of a '-' sign with no digits: after consuming the minus the parser finds length == 0 or the delimiter immediately, i.e. the field text is exactly \"-\". The sign is consumed and the digit loop would have nothing to read, so it fails fast with NumberFormatException.","triggerScenarios":"Calling ByteParser.parseField where the field slice is exactly \"-\" — a lone minus sign between delimiters, e.g. \"5,-,7\" with ',' delimiter.","commonSituations":"Dirty exports where a negative number lost its digits; placeholder '-' used for missing values in some datasets; partial writes truncating a number right after the sign.","solutions":["Clean the source data: replace bare '-' placeholders with a real value or an empty field handled explicitly.","Pre-validate the field slice (reject/skip when it equals \"-\") before calling the parser.","Add a data-quality check on incoming files for sign-only numeric fields."],"exampleFix":"// before\nbyte v = ByteParser.parseField(bytes, start, len, '|');\n\n// after\nString field = new String(bytes, start, len, StandardCharsets.UTF_8);\nif (field.equals(\"-\")) { throw new IllegalArgumentException(\"Sign-only byte field at \" + start); }\nbyte v = ByteParser.parseField(bytes, start, len, '|');","handlingStrategy":"validation","validationCode":"if (len == 1 && bytes[start] == '-') {\n    throw new IllegalArgumentException(\"Sign-only byte field\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    byte v = ByteParser.parseField(bytes, start, len, delim);\n} catch (NumberFormatException e) {\n    if (e.getMessage().equals(\"Orphaned minus sign.\")) { /* treat as missing value */ }\n    else throw e;\n}","preventionTips":["Reject sign-only placeholders at ingestion.","Standardize missing-value representation in source files (empty or explicit token).","Add regex screening (^-?\\d+$) for numeric fields from untrusted sources."],"tags":["parser","byte","malformed-number","csv","flink-core"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}