{"record":{"id":"67b2eee36bfb7f7e","repo":"apache/cassandra","slug":"all-values-must-be-either-negative-or-positive-go","errorCode":null,"errorMessage":"All values must be either negative or positive, got %d months, %d days, %d nanoseconds","messagePattern":"All values must be either negative or positive, got (.+?) months, (.+?) days, (.+?) nanoseconds","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/functions/types/Duration.java","lineNumber":89,"sourceCode":"    private final int months;\n\n    /**\n     * The number of days.\n     */\n    private final int days;\n\n    /**\n     * The number of nanoseconds.\n     */\n    private final long nanoseconds;\n\n    private Duration(int months, int days, long nanoseconds)\n    {\n        // Makes sure that all the values are negative if one of them is\n        if ((months < 0 || days < 0 || nanoseconds < 0)\n            && ((months > 0 || days > 0 || nanoseconds > 0)))\n        {\n            throw new IllegalArgumentException(\n            String.format(\n            \"All values must be either negative or positive, got %d months, %d days, %d nanoseconds\",\n            months, days, nanoseconds));\n        }\n        this.months = months;\n        this.days = days;\n        this.nanoseconds = nanoseconds;\n    }\n\n    /**\n     * Creates a duration with the given number of months, days and nanoseconds.\n     *\n     * <p>A duration can be negative. In this case, all the non zero values must be negative.\n     *\n     * @param months      the number of months\n     * @param days        the number of days\n     * @param nanoseconds the number of nanoseconds\n     * @throws IllegalArgumentException if the values are not all negative or all positive","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/functions/types/Duration.java#L71-L107","documentation":"The driver's Duration type (CQL duration) encodes months, days, and nanoseconds, and its private constructor enforces the invariant that the components must all share a sign — a duration cannot be, say, negative months with positive days, because the resulting ordering would be ambiguous. Mixed-sign components throw IllegalArgumentException with this message.","triggerScenarios":"Creating a Duration via Duration.newInstance (or a custom factory) with mixed-sign values such as (2, -3, 0), or decoding an invalid serialized duration containing mixed-sign components.","commonSituations":"Computing durations by subtracting date components independently (monthsDiff, daysDiff, nanosDiff) so components take opposite signs; hand-crafting durations to represent \"backwards\" intervals; corrupt binary input.","solutions":["Normalize the duration so all three components have the same sign before constructing (flip all or none)","Compute the interval in a single unit (e.g. total nanoseconds or months) and build the Duration from that","Validate inputs in application code before calling Duration.newInstance"],"exampleFix":"// before\nDuration d = Duration.newInstance(1, -15, 0); // mixed signs\n// after\nDuration d = Duration.newInstance(-1, -15, 0); // uniformly negative, or recompute in one unit","handlingStrategy":"validation","validationCode":"boolean mixedSign = (m < 0 || d < 0 || n < 0) && (m > 0 || d > 0 || n > 0);\nif (mixedSign) throw new IllegalArgumentException(\"duration components must share one sign\");","typeGuard":null,"tryCatchPattern":"try {\n    Duration dur = Duration.newInstance(months, days, nanos);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"negative or positive\")) {\n        // normalize signs and retry\n    }\n}","preventionTips":["Normalize sign across all three components before constructing a Duration","Compute intervals in a single unit (months or nanoseconds) rather than mixing per-component diffs","Add a sign-consistency assert in any helper that builds Duration values"],"tags":["java-driver","duration","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}