Skip to content

CefTexture creates GDExtension placeholder instances on Godot 4.6.1 (Windows) — native methods return null #178

Description

@azereki

Environment

  • Godot version: 4.6.1 stable (Steam)
  • OS: Windows 10 Home x64 (10.0.19045)
  • godot-cef version: Latest from Asset Library (.gdextension has compatibility_minimum = 4.5, entry_symbol = "gdext_rust_init")
  • Architecture: x86_64 (windows.x86_64 binaries)

Description

CefTexture instances are created as GDExtension placeholder objects. The class is registered in ClassDB and passes all reflection checks, but every native method call returns null and Godot prints:

ERROR: Cannot call GDExtension method bind 'is_loading' on placeholder instance.
ERROR: Cannot call GDExtension method bind 'send_ipc_data' on placeholder instance.

No signals (load_started, load_finished, ipc_message, etc.) ever fire. The browser subprocess never launches.

Reproduction Steps

  1. Create a new Godot 4.6.1 project
  2. Install godot-cef from the Asset Library (or copy the addons/godot_cef/ directory)
  3. Verify all DLLs are present in addons/godot_cef/bin/x86_64-pc-windows-msvc/
  4. Create a CefTexture node in an @tool EditorPlugin (or in a scene)
  5. Set url to any valid URL
  6. Call is_loading() → returns null instead of bool

Minimal reproduction in GDScript:

var browser = ClassDB.instantiate(&"CefTexture")
add_child(browser)

# These all pass — the class IS registered:
print(ClassDB.class_exists(&"CefTexture"))         # true
print(browser.has_method("is_loading"))             # true
print(browser.has_signal("load_finished"))           # true
print(browser.get_class())                           # "CefTexture"

# But native methods fail:
var result = browser.is_loading()  # → null + ERROR log
browser.url = "https://example.com"  # property storage works (no crash)
# No signals ever fire — browser subprocess never starts

Investigation

What we verified:

Check Result
ClassDB.class_exists(&"CefTexture") true
GDExtensionManager.get_loaded_extensions() Contains the godot_cef extension
has_method("is_loading") true
has_method("send_ipc_message") true
has_signal("load_finished") true
get_class() "CefTexture"
Native method call is_loading() Returns null, prints placeholder ERROR
URL property assignment No crash (property storage works on placeholders)
Any signal firing Never fires

All DLLs are present and have correct sizes:

  • gdcef.dll — 6.2 MB
  • libcef.dll — 256 MB
  • chrome_elf.dll, d3dcompiler_47.dll, dxcompiler.dll, libEGL.dll, libGLESv2.dll, vk_swiftshader.dll, vulkan-1.dll — all present
  • gdcef_helper.exe, bootstrap.exe, bootstrapc.exe — all present
  • icudtl.dat, resource paks, locale files — all present

No load errors appear in the Godot console at startup. The extension silently creates placeholders without any visible error about why the native library failed to initialize.

Analysis

This appears to be a Godot 4.6 GDExtension compatibility issue. The .gdextension file specifies compatibility_minimum = 4.5, but Godot 4.6 may have changed the GDExtension ABI or initialization sequence in a way that causes gdext_rust_init to fail silently.

The key difficulty is that Godot provides no diagnostic information when this happens — the extension is listed as "loaded," the class is registered, reflection works, but the native Rust code never executes. The only way to detect this is to call a native method and check for null return.

Possibly Related

Context

This was discovered while building GodotFlow, a visual scripting editor that uses React + Vite inside CefTexture. We implemented a workaround that detects placeholder instances via:

var probe: Variant = browser.is_loading()
if probe == null:
    push_warning("CefTexture is a GDExtension placeholder — native library did not load.")
    # Fall back to standalone mode (pnpm dev + external browser)

Feature Request

If possible, could the Rust initialization code (gdext_rust_init) log a diagnostic message when it fails to initialize? Currently there's zero console output when the DLL fails to load — the extension appears to work until you call a native method.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions