{"record":{"id":"102abdc5bf2ed468","repo":"apple/pkl","slug":"invalid-duration-unit-s","errorCode":null,"errorMessage":"Invalid Duration unit `%s`","messagePattern":"Invalid Duration unit `(.+?)`","errorType":"validation","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java","lineNumber":270,"sourceCode":"  }\n\n  private Object decodeSet(int len) throws IOException {\n    assertLength(PklBinaryCode.SET, len, 1);\n    currPath.push(\"'set\");\n    var result = doDecodeSet(new CollectionDecodeIterator(unpacker.unpackArrayHeader(), \"set\"));\n    currPath.pop();\n    unpacker.skipValue(len - 2);\n    return result;\n  }\n\n  private Object decodeDuration(int len) throws IOException {\n    assertLength(PklBinaryCode.DURATION, len, 2);\n    currPath.push(\"'duration\");\n    var durationValue = unpacker.unpackDouble();\n    var rawDurationUnit = unpacker.unpackString();\n    var durationUnit = DurationUnit.parse(rawDurationUnit);\n    if (durationUnit == null) {\n      throw new DecodeException(\"Invalid Duration unit `%s`\", rawDurationUnit);\n    }\n    var result = doDecodeDuration(durationValue, durationUnit);\n    unpacker.skipValue(len - 3);\n    currPath.pop();\n    return result;\n  }\n\n  private Object decodeDataSize(int len) throws IOException {\n    assertLength(PklBinaryCode.DATASIZE, len, 2);\n    currPath.push(\"'datasize\");\n    var dataSizeValue = unpacker.unpackDouble();\n    var rawDataSizeUnit = unpacker.unpackString();\n    var dataSizeUnit = DataSizeUnit.parse(rawDataSizeUnit);\n    if (dataSizeUnit == null) {\n      throw new DecodeException(\"Invalid DataSize unit `%s`\", rawDataSizeUnit);\n    }\n    var result = doDecodeDataSize(dataSizeValue, dataSizeUnit);\n    unpacker.skipValue(len - 3);","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java#L252-L288","documentation":"Thrown by decodeDuration when a DURATION entry's unit string cannot be parsed by DurationUnit.parse. Pkl durations support a fixed set of units (ns, us, ms, s, min, h, d); any other string is rejected as invalid input.","triggerScenarios":"Decoding pkl-binary bytes where a DURATION entry carries a unit string like \"sec\", \"seconds\", \"hrs\", or an empty string; a custom encoder writing non-canonical unit names.","commonSituations":"Third-party encoders emitting humanized unit names instead of the canonical Pkl spelling; hand-crafted test fixtures; localized/translated unit strings.","solutions":["Use canonical Pkl duration unit strings in the encoder: ns, us, ms, s, min, h, d","Normalize/alias unit names at the producer before packing","Regenerate the payload with the official Pkl encoder","Log rawDurationUnit to identify the offending value and correct the producer"],"exampleFix":"// before\npacker.packString(\"seconds\");\n// after\npacker.packString(\"s\");","handlingStrategy":"validation","validationCode":"Set<String> VALID = Set.of(\"ns\",\"us\",\"ms\",\"s\",\"min\",\"h\",\"d\");\nif (!VALID.contains(unit)) throw new IllegalArgumentException(\"bad duration unit: \" + unit);","typeGuard":null,"tryCatchPattern":"try {\n  return decoder.decode(bytes);\n} catch (DecodeException e) {\n  if (e.getMessage().contains(\"Invalid Duration unit\")) {\n    throw new MalformedPklBinaryException(e);\n  }\n  throw e;\n}","preventionTips":["Only emit canonical unit spellings (ns, us, ms, s, min, h, d)","Never humanize unit names in binary payloads","Test round-trip encode/decode for every unit","Reject bad units at encode time"],"tags":["pkl","binary-decoder","duration","enum"],"backgroundTag":"invalid-duration-format","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"}