bevyengine/bevy · error · BrpError
-32603
-32603
Error message
Unexpected format of serialized resource value
What it means
BRP's `world.get_resource(s)` handler serializes a resource with ReflectSerializer, which always emits a single-entry JSON map `{type_path: value}`; the handler then extracts that one value. If the map is empty (`into_values().next()` is None), the serializer violated that contract and the server returns an INTERNAL_ERROR (-32603). It signals a broken/custom reflection serialization for that resource type, not a bad request.
Source
Thrown at crates/bevy_remote/src/builtin_methods.rs:655
return Err(BrpError::resource_not_present(&resource_path));
};
// Use the `ReflectSerializer` to serialize the value of the resource;
// this produces a map with a single item.
let reflect_serializer = ReflectSerializer::new(reflected.as_partial_reflect(), &type_registry);
let Value::Object(serialized_object) =
serde_json::to_value(&reflect_serializer).map_err(BrpError::resource_error)?
else {
return Err(BrpError {
code: error_codes::RESOURCE_ERROR,
message: format!("Resource `{resource_path}` could not be serialized"),
data: None,
});
};
// Get the single value out of the map.
let value = serialized_object.into_values().next().ok_or_else(|| {
BrpError::internal(anyhow!("Unexpected format of serialized resource value"))
})?;
let response = BrpGetResourcesResponse { value };
serde_json::to_value(response).map_err(BrpError::internal)
}
/// Handles a `world.get_components+watch` request coming from a client.
pub fn process_remote_get_components_watching_request(
In(params): In<Option<Value>>,
world: &World,
mut removal_cursors: Local<HashMap<ComponentId, MessageCursor<RemovedComponentEntity>>>,
) -> BrpResult<Option<Value>> {
let BrpGetComponentsParams {
entity,
components,
strict,
} = parse_some(params)?;
let app_type_registry = world.resource::<AppTypeRegistry>();View on GitHub (pinned to 78002f65fa)
Solutions
- Prefer `#[derive(Reflect)]` on the resource instead of a hand-written serialization impl
- Test locally: `world.resource::<T>()` serialization via the type registry to reproduce and fix the impl
- If the type is a stock Bevy resource and this fires, search Bevy's issue tracker / upgrade — this indicates an engine-side bug
- As a client, degrade gracefully: report the resource as unreadable instead of retrying (the result is deterministic)
Example fix
// before: manual reflect serialize producing an empty map
impl ReflectSerialize for MyRes { /* returns map with no entries */ }
// after: derive-based reflection
#[derive(Resource, Reflect)]
#[reflect(Resource)]
struct MyRes { intensity: f32 } Defensive patterns
Strategy: try-catch
Validate before calling
null // no client-side pre-check; probe with world.get_resource for the same type and treat serialization failures as 'unreadable resource'
Try / catch
// BRP client (JS/TS): fetch or websocket JSON-RPC
const res = await brpCall("world.get_resource", { resource: path });
if (res.error) {
if (res.error.code === -32603 && /serialized resource value/i.test(res.error.message)) {
console.warn(`Resource ${path} is not remotely serializable; skipping`);
continue; // deterministic failure — do not retry
}
throw res.error;
} Prevention
- Stick to derived #[derive(Reflect)] serialization for resources you plan to read over BRP
- Smoke-test remote reads for every custom resource type once at tool startup
- Treat -32603 internal errors as engine bugs: collect a repro, don't build retry loops on them
When it happens
Trigger: A `world.get_resource` / `world.get_resources` BRP request against a resource whose `ReflectSerialize` type data produces an empty serialized object (hand-written reflect Serialize impls, or exotic dynamic types). The request itself is well-formed; serialization output shape is wrong.
Common situations: Custom resource types with manually implemented `Serialize`/`ReflectSerialize` that return an empty map; a version mismatch between a BRP client's expectations and the server's Bevy version; extremely rare — most derived `#[derive(Reflect)]` types always produce the single-entry map.
Related errors
- -23501
- -23402
- FullscreenMaterial::fragment_shader() must not return Shader
- Enable feature "shader_format_spirv" to use SPIR-V shaders
AI-assisted analysis of bevyengine/bevy@78002f65fa (2026-08-16).
Data as JSON: /api/errors/887dc8842a77f6e6.
Report an issue: GitHub.