didi/DoKit · error · IllegalArgumentException

Path must not be empty.

Error message

Path must not be empty.

What it means

DokitPicasso.load(String path) treats null as a deliberate no-op request (placeholder-only) but rejects empty or whitespace-only strings with IllegalArgumentException('Path must not be empty.'), because Uri.parse("") would produce a request no handler can serve. It is an argument-contract error: the caller passed a string, but it carries no usable location.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/DokitPicasso.java:298

   * <p>
   * This path may be a remote URL, file resource (prefixed with {@code file:}), content resource
   * (prefixed with {@code content:}), or android resource (prefixed with {@code
   * android.resource:}.
   * <p>
   * Passing {@code null} as a {@code path} will not trigger any request but will set a
   * placeholder, if one is specified.
   *
   * @see #load(Uri)
   * @see #load(File)
   * @see #load(int)
   * @throws IllegalArgumentException if {@code path} is empty or blank string.
   */
  public RequestCreator load(String path) {
    if (path == null) {
      return new RequestCreator(this, null, 0);
    }
    if (path.trim().length() == 0) {
      throw new IllegalArgumentException("Path must not be empty.");
    }
    return load(Uri.parse(path));
  }

  /**
   * Start an image request using the specified image file. This is a convenience method for
   * calling {@link #load(Uri)}.
   * <p>
   * Passing {@code null} as a {@code file} will not trigger any request but will set a
   * placeholder, if one is specified.
   * <p>
   * Equivalent to calling {@link #load(Uri) load(Uri.fromFile(file))}.
   *
   * @see #load(Uri)
   * @see #load(String)
   * @see #load(int)
   */
  public RequestCreator load(File file) {

View on GitHub (pinned to 626827cddb)

Solutions

  1. Normalize before loading: treat blank strings as absent, same as null
  2. Fix the producer so optional fields are null rather than empty strings
  3. Use .error(placeholder) plus the guard so the UI still shows something

Example fix

// before
DokitPicasso.with(context).load(item.avatarUrl).into(avatar); // avatarUrl == ""

// after
RequestCreator rq = (item.avatarUrl == null || item.avatarUrl.trim().isEmpty())
    ? DokitPicasso.with(context).load(R.drawable.avatar_placeholder)
    : DokitPicasso.with(context).load(item.avatarUrl);
rq.into(avatar);
Defensive patterns

Strategy: validation

Validate before calling

static boolean isBlank(String s) { return s == null || s.trim().isEmpty(); }

RequestCreator rq = isBlank(path)
    ? picasso.load(R.drawable.placeholder)
    : picasso.load(path);
rq.into(view);

Try / catch

// Cheap guard makes try-catch unnecessary; if calling untrusted code:
try {
  picasso.load(path).into(view);
} catch (IllegalArgumentException e) {
  if ("Path must not be empty.".equals(e.getMessage())) {
    view.setImageResource(R.drawable.placeholder);
  } else throw e;
}

Prevention

When it happens

Trigger: load("") or load(" ") from a model field that was never populated; data binding where the path expression evaluates to empty; trailing/leading whitespace introduced by JSON trimming bugs; lint-blocking null checks converted to empty strings.

Common situations: Feed items with an optional image URL where the server sends "" instead of null; getString(R.string.x) returning empty in flavor builds.

Related errors


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