didi/DoKit · warning · FileNotFoundException

More than two path segments: " + data.uri

Error message

More than two path segments: " + data.uri

What it means

Utils.getResourceId(Resources, Request) accepts android.resource:// URIs with at most two path segments (one = numeric ID, two = type/name). With three or more segments there is no defined meaning, so it throws FileNotFoundException('More than two path segments: <uri>').

Source

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

    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 {
    if (data.resourceId != 0 || data.uri == null) {
      return context.getResources();
    }

    String pkg = data.uri.getAuthority();
    if (pkg == null) throw new FileNotFoundException("No package provided: " + data.uri);
    try {
      PackageManager pm = context.getPackageManager();
      return pm.getResourcesForApplication(pkg);
    } catch (PackageManager.NameNotFoundException e) {
      throw new FileNotFoundException("Unable to obtain resources for package: " + data.uri);
    }
  }

View on GitHub (pinned to 626827cddb)

Solutions

  1. Normalize to exactly two segments: type + name without extension or qualifier (android.resource://pkg/drawable/ic_logo).
  2. Validate segment count before loading if URIs arrive from external sources.
  3. Use picasso.load(resId) when the resource is local and known.

Example fix

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

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

Strategy: validation

Validate before calling

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

Try / catch

Consume via error callback, log the URI, and retry with a normalized two-segment URI.

Prevention

When it happens

Trigger: Passing URIs like android.resource://pkg/drawable-hdpi/ic_logo.png or a nested path android.resource://pkg/a/b/c — anything whose getPathSegments().size() > 2.

Common situations: Appending file extensions or qualifiers to a resource name; reusing a file-path-style builder for resource URIs; a share/deep-link pipeline that preserves extra segments.

Related errors


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