Skip to content

DCHECK(created_handle_) crash in scheme_handler_factory.cpp when CefSchemeHandlerFactory serves a browser-independent CefURLRequest #24

Description

@Thrameos

Summary

Found while adding coverage for native/url_request_client.cpp (a CefURLRequest is explicitly documented as "not associated with a browser instance"). Registering a global CefApp.registerSchemeHandlerFactory() and then using it to serve a standalone CefURLRequest (rather than a browser navigation) crashes the Debug build:

FATAL:native/jni_scoped_helpers.h:639] Check failed: created_handle_.

Root cause

native/scheme_handler_factory.cpp's SchemeHandlerFactory::Create():

ScopedJNIFrame jframe(env, frame);
jframe.SetTemporary();

calls SetTemporary() unconditionally. ScopedJNIObject's constructor only sets created_handle_ = true when its obj (here, frame) is non-null:

if (obj) {
  jhandle_ = NewJNIObject(env_, jni_class_name);
  if (jhandle_) {
    created_handle_ = true;
    ...

For a standalone CefURLRequest, CEF calls CefSchemeHandlerFactory::Create() with a null frame (there is no real CefFrame -- no browser navigation is involved), so created_handle_ stays false, and the subsequent unconditional jframe.SetTemporary() trips DCHECK(created_handle_) in SetTemporary() itself (jni_scoped_helpers.h:639).

Impact

Debug/ENABLE_COVERAGE-build only (release builds don't compile DCHECKs in, per this fork's usual pattern for this class of bug -- see #9/#20/#21). Any application combining a globally-registered CefSchemeHandlerFactory with a browser-independent CefURLRequest against a matching scheme/domain would hit this in a Debug CEF build.

Suggested fix

Guard both SetTemporary() calls in SchemeHandlerFactory::Create() on whether the corresponding ScopedJNIObject actually got a handle, e.g.:

ScopedJNIFrame jframe(env, frame);
if (frame) jframe.SetTemporary();

(and the same for jrequest, if request can plausibly be null too -- not confirmed either way this session).

Repro

CefURLRequestTest.realCompletionFiresRequestCompleteAndDownloadData() in this fork -- registers a scheme handler factory, then creates a standalone CefURLRequest against a matching URL. Currently @Disabled for the Debug/coverage build; passes cleanly in the Release build (no DCHECKs compiled in), confirmed via repeated full-suite runs.

Activity

  1. Thrameos commented on Aug 30, 2026

    @Thrameos
    OwnerAuthor

    Fixed in commit `e00e35b`: guarded both `SetTemporary()` calls in `SchemeHandlerFactory::Create()` on the corresponding pointer (`frame`/`request`) being non-null, matching this issue's suggested fix exactly.

    Verified: `CefURLRequestTest.realCompletionFiresRequestCompleteAndDownloadData()` now runs and passes SUCCESSFUL in the Debug/coverage build (confirmed via `--details=verbose` across 2 full-suite runs — no more `DCHECK failed: created_handle_`). Removed the `@Tag("debug-build-crash")` workaround; it now runs as an ordinary test in both build configs. Release suite: 169/169 passing, no regressions.

  2. added a commit that references this issue on Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions