{"record":{"id":"03ba524e60ff7756","repo":"Yalantis/uCrop","slug":"s-must-implement-ucropfragmentcallback","errorCode":null,"errorMessage":"%s must implement UCropFragmentCallback","messagePattern":"(.+?) must implement UCropFragmentCallback","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/java/com/yalantis/ucrop/UCropFragment.java","lineNumber":116,"sourceCode":"    static {\n        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);\n    }\n\n    public static UCropFragment newInstance(Bundle uCrop) {\n        UCropFragment fragment = new UCropFragment();\n        fragment.setArguments(uCrop);\n        return fragment;\n    }\n\n    @Override\n    public void onAttach(Context context) {\n        super.onAttach(context);\n        if (getParentFragment() instanceof UCropFragmentCallback)\n            callback = (UCropFragmentCallback) getParentFragment();\n        else if (context instanceof UCropFragmentCallback)\n            callback = (UCropFragmentCallback) context;\n        else\n            throw new IllegalArgumentException(context.toString()\n                    + \" must implement UCropFragmentCallback\");\n    }\n\n    public void setCallback(UCropFragmentCallback callback) {\n        this.callback = callback;\n    }\n\n    @Nullable\n    @Override\n    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {\n        View rootView = inflater.inflate(R.layout.ucrop_fragment_photobox, container, false);\n\n        Bundle args = getArguments();\n\n        setupViews(rootView, args);\n        setImageData(args);\n        setInitialState();\n        addBlockingView(rootView);","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/java/com/yalantis/ucrop/UCropFragment.java#L98-L134","documentation":"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.","triggerScenarios":"Adding UCropFragment to an Activity (or a fragment container) whose Activity and parent fragment both do not implement UCropFragmentCallback, without calling fragment.setCallback() first.","commonSituations":"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.","solutions":["Make the hosting Activity implement UCropFragmentCallback.","Or make the parent Fragment implement UCropFragmentCallback.","If neither is possible, obtain the fragment instance and call setCallback(yourCallback) right after creating it, before transaction commit returns.","Downgrade to UCropActivity-based intent flow if a callback host cannot be provided."],"exampleFix":"// before\npublic class EditorActivity extends AppCompatActivity {\n    getSupportFragmentManager().beginTransaction()\n        .add(R.id.container, UCropFragment.newInstance(bundle)).commit();\n}\n// after\npublic class EditorActivity extends AppCompatActivity implements UCropFragmentCallback {\n    getSupportFragmentManager().beginTransaction()\n        .add(R.id.container, UCropFragment.newInstance(bundle)).commit();\n}","handlingStrategy":"type-guard","validationCode":"if (!(activity instanceof UCropFragmentCallback) &&\n    (getParentFragment() == null || !(getParentFragment() instanceof UCropFragmentCallback))) {\n    throw new IllegalStateException(\"Host must implement UCropFragmentCallback or call setCallback()\");\n}","typeGuard":"UCropFragmentCallback resolveCallback(Fragment f, Context ctx) {\n    if (f.getParentFragment() instanceof UCropFragmentCallback) return (UCropFragmentCallback) f.getParentFragment();\n    if (ctx instanceof UCropFragmentCallback) return (UCropFragmentCallback) ctx;\n    return null; // then use fragment.setCallback(...) with a non-null callback\n}","tryCatchPattern":"try {\n    fragmentManager.beginTransaction().add(R.id.container, UCropFragment.newInstance(bundle)).commit();\n} catch (IllegalArgumentException e) {\n    fragment.setCallback(this); // or implement UCropFragmentCallback on the host\n}","preventionTips":["Have the hosting Activity implement UCropFragmentCallback when using the fragment API.","When nesting fragments (ViewPager, dialogs), rely on setCallback() explicitly rather than interface detection.","Keep UCropFragment and UCropActivity usage patterns consistent across your app.","Add a debug-time assert that the callback resolves before committing the fragment transaction."],"tags":["android","ucrop","fragment","callback","illegal-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}