Yalantis/uCrop · error · IllegalArgumentException

%s must implement UCropFragmentCallback

Error message

%s must implement UCropFragmentCallback

What it means

UCropFragment requires a callback channel: during onAttach it looks for UCropFragmentCallback on the parent fragment, then on the hosting Activity context. If neither implements it and no callback was set explicitly, it throws IllegalArgumentException because the fragment would have no way to deliver crop results.

Source

Thrown at ucrop/src/main/java/com/yalantis/ucrop/UCropFragment.java:116

    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    public static UCropFragment newInstance(Bundle uCrop) {
        UCropFragment fragment = new UCropFragment();
        fragment.setArguments(uCrop);
        return fragment;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (getParentFragment() instanceof UCropFragmentCallback)
            callback = (UCropFragmentCallback) getParentFragment();
        else if (context instanceof UCropFragmentCallback)
            callback = (UCropFragmentCallback) context;
        else
            throw new IllegalArgumentException(context.toString()
                    + " must implement UCropFragmentCallback");
    }

    public void setCallback(UCropFragmentCallback callback) {
        this.callback = callback;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.ucrop_fragment_photobox, container, false);

        Bundle args = getArguments();

        setupViews(rootView, args);
        setImageData(args);
        setInitialState();
        addBlockingView(rootView);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Make the hosting Activity implement UCropFragmentCallback.
  2. Or make the parent Fragment implement UCropFragmentCallback.
  3. If neither is possible, obtain the fragment instance and call setCallback(yourCallback) right after creating it, before transaction commit returns.
  4. Downgrade to UCropActivity-based intent flow if a callback host cannot be provided.

Example fix

// before
public class EditorActivity extends AppCompatActivity {
    getSupportFragmentManager().beginTransaction()
        .add(R.id.container, UCropFragment.newInstance(bundle)).commit();
}
// after
public class EditorActivity extends AppCompatActivity implements UCropFragmentCallback {
    getSupportFragmentManager().beginTransaction()
        .add(R.id.container, UCropFragment.newInstance(bundle)).commit();
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(activity instanceof UCropFragmentCallback) &&
    (getParentFragment() == null || !(getParentFragment() instanceof UCropFragmentCallback))) {
    throw new IllegalStateException("Host must implement UCropFragmentCallback or call setCallback()");
}

Type guard

UCropFragmentCallback resolveCallback(Fragment f, Context ctx) {
    if (f.getParentFragment() instanceof UCropFragmentCallback) return (UCropFragmentCallback) f.getParentFragment();
    if (ctx instanceof UCropFragmentCallback) return (UCropFragmentCallback) ctx;
    return null; // then use fragment.setCallback(...) with a non-null callback
}

Try / catch

try {
    fragmentManager.beginTransaction().add(R.id.container, UCropFragment.newInstance(bundle)).commit();
} catch (IllegalArgumentException e) {
    fragment.setCallback(this); // or implement UCropFragmentCallback on the host
}

Prevention

When it happens

Trigger: Adding UCropFragment to an Activity (or a fragment container) whose Activity and parent fragment both do not implement UCropFragmentCallback, without calling fragment.setCallback() first.

Common situations: Integrating uCrop into a plain AppCompatActivity without implementing the interface; hosting the fragment inside a ViewPager/DialogFragment container where the parent fragment isn't the callback owner; migrating from UCropActivity to the fragment-based flow.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/03ba524e60ff7756. Report an issue: GitHub.