apple/pkl · error · DecodeException

Invalid Duration unit `%s`

Error message

Invalid Duration unit `%s`

What it means

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.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/util/pklbinary/AbstractPklBinaryDecoder.java:270

  }

  private Object decodeSet(int len) throws IOException {
    assertLength(PklBinaryCode.SET, len, 1);
    currPath.push("'set");
    var result = doDecodeSet(new CollectionDecodeIterator(unpacker.unpackArrayHeader(), "set"));
    currPath.pop();
    unpacker.skipValue(len - 2);
    return result;
  }

  private Object decodeDuration(int len) throws IOException {
    assertLength(PklBinaryCode.DURATION, len, 2);
    currPath.push("'duration");
    var durationValue = unpacker.unpackDouble();
    var rawDurationUnit = unpacker.unpackString();
    var durationUnit = DurationUnit.parse(rawDurationUnit);
    if (durationUnit == null) {
      throw new DecodeException("Invalid Duration unit `%s`", rawDurationUnit);
    }
    var result = doDecodeDuration(durationValue, durationUnit);
    unpacker.skipValue(len - 3);
    currPath.pop();
    return result;
  }

  private Object decodeDataSize(int len) throws IOException {
    assertLength(PklBinaryCode.DATASIZE, len, 2);
    currPath.push("'datasize");
    var dataSizeValue = unpacker.unpackDouble();
    var rawDataSizeUnit = unpacker.unpackString();
    var dataSizeUnit = DataSizeUnit.parse(rawDataSizeUnit);
    if (dataSizeUnit == null) {
      throw new DecodeException("Invalid DataSize unit `%s`", rawDataSizeUnit);
    }
    var result = doDecodeDataSize(dataSizeValue, dataSizeUnit);
    unpacker.skipValue(len - 3);

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Use canonical Pkl duration unit strings in the encoder: ns, us, ms, s, min, h, d
  2. Normalize/alias unit names at the producer before packing
  3. Regenerate the payload with the official Pkl encoder
  4. Log rawDurationUnit to identify the offending value and correct the producer

Example fix

// before
packer.packString("seconds");
// after
packer.packString("s");
Defensive patterns

Strategy: validation

Validate before calling

Set<String> VALID = Set.of("ns","us","ms","s","min","h","d");
if (!VALID.contains(unit)) throw new IllegalArgumentException("bad duration unit: " + unit);

Try / catch

try {
  return decoder.decode(bytes);
} catch (DecodeException e) {
  if (e.getMessage().contains("Invalid Duration unit")) {
    throw new MalformedPklBinaryException(e);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Third-party encoders emitting humanized unit names instead of the canonical Pkl spelling; hand-crafted test fixtures; localized/translated unit strings.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/102abdc5bf2ed468. Report an issue: GitHub.