nathanmarz/storm · error · RuntimeException
State query operation can only have one parent
Error message
State query operation can only have one parent
What it means
StateQueryProcessor.prepare requires exactly one parent tuple factory because stateQuery reads from one input stream. If the parent count is not 1, prepare throws this RuntimeException. The state-query node was connected to multiple (or zero) upstream streams in the Trident graph.
Solutions
- Ensure stateQuery is applied to a Stream with a single parent; restructure joins/merges so the query node has in-degree 1.
- Apply stateQuery after the join output stream, not with join parents wired directly to it.
- Fix custom graph construction so the StateQueryProcessor node has exactly one incoming edge.
- Verify with the topology that only the intended stream feeds the state query.
Example fix
// before: two parents wired to the stateQuery node joinNode -> stateQueryNode; s2 -> stateQueryNode; // after: join output is the single parent Stream joined = s1.join(s2, ...); joined.stateQuery(stateFactory, fields, queryFunction);
Defensive patterns
Strategy: validation
Validate before calling
// Java: verify query node has a single parent before topology build
if (queryNode.getParents().size() != 1) {
throw new IllegalArgumentException("stateQuery requires exactly one parent stream");
} Try / catch
try { stream.stateQuery(...); } catch (RuntimeException e) { if (e.getMessage().contains("can only have one parent")) { throw new TopologyStructureException("stateQuery wired to multiple parents", e); } throw e; } Prevention
- Query state only from single-parent streams (e.g. DRPC join output)
- Do not wire extra edges into the stateQuery node in custom graphs
- Test DRPC topologies locally before cluster deploy
When it happens
Trigger: Calling TridentTopology.newDRPCStream().stateQuery(...) or Stream.stateQuery(...) where the underlying node has multiple parent tuple factories, typically from manual graph wiring or querying a stream with several upstream edges.
Common situations: DRPC topologies where the query node got extra upstream edges from custom assembly; joins feeding stateQuery with unmerged parents; refactors adding inputs to a query node.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Cannot join DRPC stream with streams originating from other…
- Aggregate operation can only have one parent
- Each operation can only have one parent
- Partition persist operation can only have one parent
- Projection processor can only have one parent
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/80537c22edc7e580.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/storm/trident/planner/processor/StateQueryProcessor.java:54
QueryFunction _function;
State _state;
String _stateId;
TridentContext _context;
Fields _inputFields;
ProjectionFactory _projection;
AppendCollector _collector;
public StateQueryProcessor(String stateId, Fields inputFields, QueryFunction function) {
_stateId = stateId;
_function = function;
_inputFields = inputFields;
}
@Override
public void prepare(Map conf, TopologyContext context, TridentContext tridentContext) {
List<Factory> parents = tridentContext.getParentTupleFactories();
if(parents.size()!=1) {
throw new RuntimeException("State query operation can only have one parent");
}
_context = tridentContext;
_state = (State) context.getTaskData(_stateId);
_projection = new ProjectionFactory(parents.get(0), _inputFields);
_collector = new AppendCollector(tridentContext);
_function.prepare(conf, new TridentOperationContext(context, _projection));
}
@Override
public void cleanup() {
_function.cleanup();
}
@Override
public void startBatch(ProcessorContext processorContext) {
processorContext.state[_context.getStateIndex()] = new BatchState();
}
View on GitHub (pinned to cdb116e942)