{"record":{"id":"830ddf79cdb28d2e","repo":"didi/DoKit","slug":"cannot-use-placeholder-or-error-drawables-with-rem","errorCode":null,"errorMessage":"Cannot use placeholder or error drawables with remote views.","messagePattern":"Cannot use placeholder or error drawables with remote views\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/RequestCreator.java","lineNumber":568,"sourceCode":"    /**\n     * Asynchronously fulfills the request into the specified {@link RemoteViews} object with the\n     * given {@code viewId}. This is used for loading bitmaps into a {@link Notification}.\n     */\n    public void into(RemoteViews remoteViews, int viewId, int notificationId,\n                     Notification notification) {\n        long started = System.nanoTime();\n\n        if (remoteViews == null) {\n            throw new IllegalArgumentException(\"RemoteViews must not be null.\");\n        }\n        if (notification == null) {\n            throw new IllegalArgumentException(\"Notification must not be null.\");\n        }\n        if (deferred) {\n            throw new IllegalStateException(\"Fit cannot be used with RemoteViews.\");\n        }\n        if (placeholderDrawable != null || placeholderResId != 0 || errorDrawable != null) {\n            throw new IllegalArgumentException(\n                    \"Cannot use placeholder or error drawables with remote views.\");\n        }\n\n        Request request = createRequest(started);\n        String key = createKey(request, new StringBuilder()); // Non-main thread needs own builder.\n\n        RemoteViewsAction action =\n                new NotificationAction(picasso, request, remoteViews, viewId, notificationId, notification,\n                        memoryPolicy, networkPolicy, key, tag, errorResId);\n\n        performRemoteViewInto(action);\n    }\n\n    /**\n     * Asynchronously fulfills the request into the specified {@link RemoteViews} object with the\n     * given {@code viewId}. This is used for loading bitmaps into all instances of a widget.\n     */\n    public void into(RemoteViews remoteViews, int viewId, int[] appWidgetIds) {","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/picasso/RequestCreator.java#L550-L586","documentation":"Thrown by RequestCreator.into(RemoteViews, int, int, Notification) when the request has a placeholder Drawable, placeholder resource, or error Drawable set. RemoteViews are rendered in another process (SystemUI), which cannot deserialize arbitrary in-process Drawable instances; only resource IDs (such as the permitted errorResId) can travel across the RemoteViews boundary. The library therefore rejects drawable-based placeholders/errors before creating the action.","triggerScenarios":"Calling .placeholder(Drawable), .placeholder(int resId), or .error(Drawable) on the builder and then into(remoteViews, viewId, notificationId, notification); the check fires for placeholderDrawable != null, placeholderResId != 0, or errorDrawable != null.","commonSituations":"Reusing a shared request configuration (with placeholders for lists) for notification icons; migrating an ImageView load that showed a spinner drawable while loading to a notification load.","solutions":["Remove .placeholder(...) and .error(Drawable) calls from the request used for RemoteViews/notification loads.","If an error image is needed, use .error(int errorResId) — the resource-ID form is explicitly passed through to NotificationAction and is allowed.","Extract the RemoteViews request construction into its own helper so UI placeholders are not accidentally applied."],"exampleFix":"// before\npicasso.load(url)\n    .placeholder(R.id.progress) // or a Drawable\n    .error(errorDrawable)\n    .into(remoteViews, R.id.icon, notifId, notification);\n\n// after\npicasso.load(url)\n    .error(R.drawable.ic_notification_error) // resource ID form is allowed\n    .into(remoteViews, R.id.icon, notifId, notification);","handlingStrategy":"validation","validationCode":"// Build notification requests without drawable placeholders\nRequestCreator rc = picasso.load(url).error(R.drawable.ic_notif_error);\n// do NOT call rc.placeholder(drawable/resId) or rc.error(Drawable)\nrc.into(remoteViews, viewId, notifId, notification);","typeGuard":null,"tryCatchPattern":"Not applicable — deterministic precondition violation; correct the request construction instead of catching.","preventionTips":["Keep a dedicated builder for RemoteViews loads that only sets errorResId.","Avoid global request customizers that inject placeholders into every request.","Remember RemoteViews render cross-process: only resource IDs can be sent."],"tags":["android","picasso","remoteviews","notification","drawable","api-misuse"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}