{"record":{"id":"35da9810815c0d9e","repo":"TheAlgorithms/Java","slug":"n-must-be-non-negative-35da98","errorCode":null,"errorMessage":"n must be non-negative.","messagePattern":"n must be non-negative\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/maths/NthUglyNumber.java","lineNumber":45,"sourceCode":"     */\n    NthUglyNumber(final int[] baseNumbers) {\n        if (baseNumbers.length == 0) {\n            throw new IllegalArgumentException(\"baseNumbers must be non-empty.\");\n        }\n\n        for (final var baseNumber : baseNumbers) {\n            this.positions.add(MutablePair.of(baseNumber, 0));\n        }\n    }\n\n    /**\n     * @param n the zero-based-index of the queried ugly number\n     * @exception IllegalArgumentException n is negative\n     * @return the n-th ugly number (starting from index 0)\n     */\n    public Long get(final int n) {\n        if (n < 0) {\n            throw new IllegalArgumentException(\"n must be non-negative.\");\n        }\n\n        while (uglyNumbers.size() <= n) {\n            addUglyNumber();\n        }\n\n        return uglyNumbers.get(n);\n    }\n\n    private void addUglyNumber() {\n        uglyNumbers.add(computeMinimalCandidate());\n        updatePositions();\n    }\n\n    private void updatePositions() {\n        final var lastUglyNumber = uglyNumbers.get(uglyNumbers.size() - 1);\n        for (var entry : positions) {\n            if (computeCandidate(entry) == lastUglyNumber) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/maths/NthUglyNumber.java#L27-L63","documentation":"Thrown by NthUglyNumber.get(int n) when n is negative. The method lazily generates ugly numbers up to index n and caches them; a negative index is meaningless for a zero-based sequence and would break the generation loop. The guard fires before the while-loop that populates the cache.","triggerScenarios":"Calling get(-1), get(-5), or any get(n) where n < 0. Common when n is computed from an expression like (count - k) that can go negative.","commonSituations":"User-supplied index not sanitized before the call; off-by-one in a loop bound (e.g., loop from n down to 0 inclusive when it should be exclusive); arithmetic on array lengths producing a negative result; parsed integer from a request payload that accepted negatives.","solutions":["Clamp or reject the index at the caller: if (n < 0) handle the invalid request.","Fix the upstream arithmetic producing the negative value (check loop bounds, length calculations).","If a negative index should map to something meaningful in your domain, remap it before calling get."],"exampleFix":"// before\nLong val = ugly.get(requestedIndex);\n\n// after\nif (requestedIndex < 0) {\n    throw new IndexOutOfBoundsException(\"index \" + requestedIndex);\n}\nLong val = ugly.get(requestedIndex);","handlingStrategy":"validation","validationCode":"if (n < 0) {\n    throw new IllegalArgumentException(\"n must be >= 0: \" + n);\n}\nLong val = ugly.get(n);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Sanitize user-supplied indices before passing to sequence accessors.","Audit arithmetic that computes indices (subtractions, decrements) for negative results.","Treat a negative index as a caller bug, not a recoverable condition."],"tags":["math","sequence","invalid-argument","negative-index"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}