{"record":{"id":"9e152891264b0271","repo":"apple/pkl","slug":"missingversioninpackageuri-9e1528","errorCode":"missingVersionInPackageUri","errorMessage":"ErrorMessages.create(\"missingVersionInPackageUri\", uriStr)","messagePattern":"ErrorMessages\\.create\\(\"missingVersionInPackageUri\", uriStr\\)","errorType":"error_code","errorClass":"URISyntaxException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/project/CanonicalPackageUri.java","lineNumber":58,"sourceCode":"              \"package\",\n              // userinfo isn't considered part of the package identifier.\n              null,\n              uri.getHost(),\n              uri.getPort(),\n              packageUri.getPathWithoutVersion(),\n              // query params aren't considered part of the package identifier.\n              null,\n              null);\n    } catch (URISyntaxException e) {\n      throw PklBugException.unreachableCode();\n    }\n    return new CanonicalPackageUri(baseUri, packageUri.getVersion().getMajor());\n  }\n\n  public static CanonicalPackageUri of(String uriStr) throws URISyntaxException {\n    var versionIdx = uriStr.lastIndexOf('@');\n    if (versionIdx == -1) {\n      throw new URISyntaxException(\n          uriStr, ErrorMessages.create(\"missingVersionInPackageUri\", uriStr));\n    }\n    int majorVersion;\n    try {\n      majorVersion = Integer.parseInt(uriStr.substring(versionIdx + 1));\n    } catch (NumberFormatException e) {\n      throw new URISyntaxException(uriStr, ErrorMessages.create(\"\"));\n    }\n    var baseUri = new URI(uriStr.substring(0, versionIdx));\n    return new CanonicalPackageUri(baseUri, majorVersion);\n  }\n\n  /**\n   * @deprecated As of 0.28.0, replaced by {@link #majorVersion()}.\n   */\n  @Deprecated(forRemoval = true)\n  public int getMajorVersion() {\n    return majorVersion;","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/project/CanonicalPackageUri.java#L40-L76","documentation":"Thrown by CanonicalPackageUri.of(String) when the URI string contains no '@' separator, so no version can be extracted. Canonical package URIs require an '@<majorVersion>' suffix to compute the canonical major-version form.","triggerScenarios":"Calling CanonicalPackageUri.of(uriStr) with a version-less string like 'package://example.com/my-pkg'; lastIndexOf('@') returns -1.","commonSituations":"Passing a bare package name or registry base URI instead of the full versioned URI; code that strips the version before canonicalization; legacy configs predating version pinning.","solutions":["Include the version in the input string, e.g. 'package://example.com/my-pkg@1.2.3'","Ensure the version-bearing portion is not stripped by preprocessing code","Parse with full PackageUri and use the other CanonicalPackageUri.of overload that accepts a parsed PackageUri"],"exampleFix":"// before\nvar canonical = CanonicalPackageUri.of(\"package://example.com/my-pkg\");\n// after\nvar canonical = CanonicalPackageUri.of(\"package://example.com/my-pkg@1.2.3\");","handlingStrategy":"validation","validationCode":"boolean canCanonicalize(String uriStr) {\n  if (uriStr == null) return false;\n  int idx = uriStr.lastIndexOf('@');\n  if (idx == -1) return false;\n  try { Integer.parseInt(uriStr.substring(idx + 1)); return true; }\n  catch (NumberFormatException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  var canonical = CanonicalPackageUri.of(uriStr);\n} catch (URISyntaxException e) {\n  throw new IllegalArgumentException(\"Package URI missing '@<version>': \" + uriStr, e);\n}","preventionTips":["Pass the full versioned URI string, never a bare package name","Keep the '@version' suffix through any preprocessing","Prefer the CanonicalPackageUri.of(PackageUri) overload for parsed URIs"],"tags":["pkl","package-uri","version","canonicalization"],"backgroundTag":"missing-required-field-in-uri","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}