apple/pkl · error · ConversionException

Error invoking constructor `%s`.

Error message

Error invoking constructor `%s`.

What it means

After all constructor arguments are converted, pkl-config-java invokes the target constructor via a MethodHandle (invokeWithArguments). If the invocation throws any Throwable — e.g. the constructor's own validation code threw, arguments are wrong after conversion, or the handle's type doesn't match the arguments — it is wrapped in this ConversionException with the constructor handle in the message.

Source

Thrown at pkl-config-java/src/main/java/org/pkl/config/java/mapper/PObjectToDataObject.java:228

        } catch (ConversionException e) {
          throw new ConversionException(
              String.format(
                  "Error converting property `%s` in Pkl object of type `%s` "
                      + "to equally named constructor parameter in Java class `%s`: "
                      + e.getMessage(),
                  param.first,
                  value.getClassInfo(),
                  Reflection.toRawType(targetType).getTypeName()),
              e.getCause());
        }
      }

      try {
        @SuppressWarnings("unchecked")
        var result = (T) constructorHandle.invokeWithArguments(args);
        return result;
      } catch (Throwable t) {
        throw new ConversionException(
            String.format("Error invoking constructor `%s`.", constructorHandle), t);
      }
    }
  }
}

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Inspect the cause chain (getCause()) — the real exception is thrown by your constructor body; fix the constructor or the offending config value.
  2. Fix the Pkl value so it passes the constructor's validation (e.g. valid ranges, non-null fields).
  3. If a null is being passed to a primitive parameter, change the Java parameter to a wrapper type or give the Pkl property a non-null default.
  4. Ensure the converted class and its dependencies load cleanly (no static initializer failures, consistent class versions).

Example fix

// before: constructor rejects config value
public Server(int port) {
  if (port <= 0) throw new IllegalArgumentException("port must be > 0");
  ...
}
// config: port = -1

// after
// config: port = 8080
Defensive patterns

Strategy: try-catch

Try / catch

try {
  return converter.convert(pklObject, valueMapper);
} catch (ConversionException e) {
  if (e.getMessage().startsWith("Error invoking constructor")) {
    Throwable root = e;
    while (root.getCause() != null) root = root.getCause();
    throw new ConfigLoadException("Constructor rejected config values: " + root, root);
  }
  throw e;
}

Prevention

When it happens

Trigger: Converter.convert reaching constructorHandle.invokeWithArguments(args) where the constructor body throws (IllegalArgumentException on validation, NPE, custom checks), or argument arity/types mismatch the MethodHandle signature (e.g. null passed to a primitive parameter).

Common situations: Java constructor performs validation (e.g. requires port > 0) and the Pkl config violates it; null Pkl value mapped into a primitive parameter; class initialization failure (ExceptionInInitializerError); incompatible cached converter after hot code replacement.

Related errors


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