Summary
When torii indexes more than one world (multiple WORLD: entries in indexing.contracts) and those worlds register models with identical (namespace, name) — e.g. several instances of the same game deployed from the same code — the GraphQL schema build panics and takes the whole process down (indexer included):
thread 'torii-query' panicked at .../async-graphql-7.0.11/src/dynamic/object.rs:82:9:
Field `s1EternumAgentConfigModels` already exists
Error: GraphQL server task panicked: task 65 panicked with message "Field `s1EternumAgentConfigModels` already exists"
Reproduction
- torii v1.8.16, katana v1.8.0-rc.9
sozo migrate the same project twice with two different world seeds
- run one torii with both worlds:
indexing.contracts = ["WORLD:<w1>", "WORLD:<w2>"]
- torii indexes both correctly (storage rows are world_address-scoped), then exits when the GraphQL schema builds
Cause
crates/graphql/src/schema.rs build_objects() does SELECT * FROM models across all worlds and derives GraphQL field/type names from (namespace, name) only (utils::field_name_from_names) — the same model registered by two worlds produces a duplicate dynamic field, and async-graphql panics. Still the case on main.
Fix
Dedupe models by (namespace, name) in build_objects() — world-scoped access remains available via SQL and gRPC, and single-world deployments are unaffected. We run this patch in production; PR incoming.
Summary
When torii indexes more than one world (multiple
WORLD:entries inindexing.contracts) and those worlds register models with identical(namespace, name)— e.g. several instances of the same game deployed from the same code — the GraphQL schema build panics and takes the whole process down (indexer included):Reproduction
sozo migratethe same project twice with two different world seedsindexing.contracts = ["WORLD:<w1>", "WORLD:<w2>"]Cause
crates/graphql/src/schema.rsbuild_objects()doesSELECT * FROM modelsacross all worlds and derives GraphQL field/type names from(namespace, name)only (utils::field_name_from_names) — the same model registered by two worlds produces a duplicate dynamic field, and async-graphql panics. Still the case onmain.Fix
Dedupe models by
(namespace, name)inbuild_objects()— world-scoped access remains available via SQL and gRPC, and single-world deployments are unaffected. We run this patch in production; PR incoming.