didi/DoKit · error · IllegalArgumentException

Transformation key must not be null.

Error message

Transformation key must not be null.

What it means

Thrown by Request.Builder.transform(Transformation) when the transformation object is non-null but its key() method returns null. The key string identifies the transformation in Picasso's cache keys; a null key makes cached results unaddressable, so it is rejected.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/Request.java:430

      }
      if (this.priority != null) {
        throw new IllegalStateException("Priority already set.");
      }
      this.priority = priority;
      return this;
    }

    /**
     * Add a custom transformation to be applied to the image.
     * <p>
     * Custom transformations will always be run after the built-in transformations.
     */
    public Builder transform(com.didichuxing.doraemonkit.picasso.Transformation transformation) {
      if (transformation == null) {
        throw new IllegalArgumentException("Transformation must not be null.");
      }
      if (transformation.key() == null) {
        throw new IllegalArgumentException("Transformation key must not be null.");
      }
      if (transformations == null) {
        transformations = new ArrayList<com.didichuxing.doraemonkit.picasso.Transformation>(2);
      }
      transformations.add(transformation);
      return this;
    }

    /**
     * Add a list of custom transformations to be applied to the image.
     * <p>
     * Custom transformations will always be run after the built-in transformations.
     */
    public Builder transform(List<? extends Transformation> transformations) {
      if (transformations == null) {
        throw new IllegalArgumentException("Transformation list must not be null.");
      }
      for (int i = 0, size = transformations.size(); i < size; i++) {

View on GitHub (pinned to 626827cddb)

Solutions

  1. Implement key() to return a stable non-null string describing the transformation (e.g., "circle()" or "rounded(radius=8)").
  2. Include parameters in the key so different configurations produce different cache entries.
  3. Add a unit test asserting key() != null for every custom Transformation.

Example fix

// before
class CircleTransform implements Transformation {
  public String key() { return null; }
  ...
}

// after
class CircleTransform implements Transformation {
  public String key() { return "circle()"; }
  ...
}
Defensive patterns

Strategy: validation

Validate before calling

if (transformation != null && transformation.key() != null) { builder.transform(transformation); }

Type guard

static boolean hasValidKey(Transformation t) {
  return t != null && t.key() != null && !t.key().isEmpty();
}

Prevention

When it happens

Trigger: Passing a custom Transformation whose key() returns null (e.g., string concatenation that yielded null, or a stub implementation).

Common situations: Writing a custom Transformation and leaving key() unimplemented or returning a null field; key() built from a nullable config field; copied skeleton code with 'return null;' left in.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/a1c3070845efb897. Report an issue: GitHub.