{"record":{"id":"535a93c3e9defc40","repo":"apple/pkl","slug":"expectedpositivenumber","errorCode":"expectedPositiveNumber","errorMessage":"expectedPositiveNumber","messagePattern":"expectedPositiveNumber","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java","lineNumber":604,"sourceCode":"  @TruffleBoundary\n  public static StringBuilder createBuilder() {\n    return new StringBuilder();\n  }\n\n  @TruffleBoundary\n  public static void appendToBuilder(StringBuilder builder, String string) {\n    builder.append(string);\n  }\n\n  @TruffleBoundary\n  public static String builderToString(StringBuilder builder) {\n    return builder.toString();\n  }\n\n  public static void checkPositive(long n) {\n    if (n < 0) {\n      CompilerDirectives.transferToInterpreter();\n      throw new VmExceptionBuilder().evalError(\"expectedPositiveNumber\", n).build();\n    }\n  }\n\n  public static Source loadSource(ResolvedModuleKey resolvedKey) {\n    try {\n      var text = resolvedKey.loadSource();\n      return createSource(resolvedKey.getOriginal(), text);\n    } catch (IOException e) {\n      throw new VmExceptionBuilder()\n          .evalError(\"ioErrorLoadingModule\", resolvedKey.getOriginal().getUri())\n          .withCause(e)\n          .build();\n    }\n  }\n\n  public static Source createSource(ModuleKey moduleKey, String text) {\n    return Source.newBuilder(\"pkl\", text, moduleKey.getUri().toString())\n        .mimeType(VmLanguage.MIME_TYPE)","sourceCodeStart":586,"sourceCodeEnd":622,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/runtime/VmUtils.java#L586-L622","documentation":"`VmUtils.checkPositive` throws expectedPositiveNumber when given a negative long. Pkl APIs that require a count/size/length argument (e.g. repeat counts, string/list slicing sizes) funnel through this check.","triggerScenarios":"Passing a negative value to any stdlib operation that calls `VmUtils.checkPositive(n)`, such as `List.repeat(n)`, `String.repeat(n)`, or length/size arguments computed to be negative.","commonSituations":"Computing a repeat/slice count from a subtraction that underflows (e.g. `b - a` with b < a), user-supplied config numbers that were not validated.","solutions":["Validate the argument is >= 0 at the call site before invoking the API.","Fix the expression producing the negative number (order of operands, wrong sign).","Clamp with `n.max(0)` if a zero-size result is acceptable.","Add a config-level constraint (e.g. a property whose type excludes negatives) so bad values fail at validation."],"exampleFix":"// before\nval padding = (end - start).repeat(\"\")\n// after\nval width = end - start\nval padding = if (width > 0) \"\".repeat(width) else \"\"","handlingStrategy":"validation","validationCode":"function requireNonNegative(n) { if (n < 0) throw new Error(\"expected non-negative value, got \" + n); return n; }","typeGuard":"function isNonNegativeInt(n) { return Number.isInteger(n) && n >= 0; }","tryCatchPattern":"try { repeat(n) } catch (e) { /* negative count */ n = 0; }","preventionTips":["Validate user/config numbers before use","Recheck subtraction order in computed counts","Clamp counts with max(0) where zero is meaningful"],"tags":["pkl","argument-validation","math"],"backgroundTag":"invalid-argument-value","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}