didi/DoKit · warning · FileNotFoundException

No path segments: " + data.uri

Error message

No path segments: " + data.uri

What it means

Utils.getResourceId(Resources, Request) parses the path segments of an android.resource:// URI to find the resource. A URI whose path is empty yields no segments, so there is nothing to resolve (neither a numeric ID nor type/name pair), and the method throws FileNotFoundException('No path segments: <uri>'). Like the other resolution failures it feeds the request's error path.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/Utils.java:343

      // If a file's header starts with RIFF and end with WEBP, the file is a WebP file
      isWebPFile = WEBP_FILE_HEADER_RIFF.equals(new String(fileHeaderBytes, 0, 4, "US-ASCII"))
          && WEBP_FILE_HEADER_WEBP.equals(new String(fileHeaderBytes, 8, 4, "US-ASCII"));
    }
    return isWebPFile;
  }

  static int getResourceId(Resources resources, Request data) throws FileNotFoundException {
    if (data.resourceId != 0 || data.uri == null) {
      return data.resourceId;
    }

    String pkg = data.uri.getAuthority();
    if (pkg == null) throw new FileNotFoundException("No package provided: " + data.uri);

    int id;
    List<String> segments = data.uri.getPathSegments();
    if (segments == null || segments.isEmpty()) {
      throw new FileNotFoundException("No path segments: " + data.uri);
    } else if (segments.size() == 1) {
      try {
        id = Integer.parseInt(segments.get(0));
      } catch (NumberFormatException e) {
        throw new FileNotFoundException("Last path segment is not a resource ID: " + data.uri);
      }
    } else if (segments.size() == 2) {
      String type = segments.get(0);
      String name = segments.get(1);

      id = resources.getIdentifier(name, type, pkg);
    } else {
      throw new FileNotFoundException("More than two path segments: " + data.uri);
    }
    return id;
  }

  static Resources getResources(Context context, Request data) throws FileNotFoundException {

View on GitHub (pinned to 626827cddb)

Solutions

  1. Include the path: android.resource://<package>/<type>/<name> or android.resource://<package>/<numeric_id>.
  2. Prefer picasso.load(resId) for local resources.
  3. Add a debug assertion that uri.getPathSegments() is non-empty before loading.

Example fix

// before
Uri uri = Uri.parse("android.resource://com.example.app/"); // empty path
picasso.load(uri).into(imageView);

// after
Uri uri = Uri.parse("android.resource://com.example.app/drawable/foo");
picasso.load(uri).into(imageView);
Defensive patterns

Strategy: validation

Validate before calling

boolean hasPathSegments(Uri uri) {
    List<String> s = uri.getPathSegments();
    return s != null && !s.isEmpty();
}

Try / catch

Handle in the request error callback: log the URI and fall back to a bundled resource.

Prevention

When it happens

Trigger: Passing a URI such as android.resource://com.example.app (empty path) or android.resource://com.example.app/ to picasso.load(); trailing-segment stripped by string manipulation.

Common situations: Building the URI from authority only and forgetting appendPath; a URI builder bug that drops path components; dynamically assembled URIs where the resource name variable was empty.

Related errors


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