{"record":{"id":"80537c22edc7e580","repo":"nathanmarz/storm","slug":"state-query-operation-can-only-have-one-parent","errorCode":null,"errorMessage":"State query operation can only have one parent","messagePattern":"State query operation can only have one parent","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"storm-core/src/jvm/storm/trident/planner/processor/StateQueryProcessor.java","lineNumber":54,"sourceCode":"    QueryFunction _function;\n    State _state;\n    String _stateId;\n    TridentContext _context;\n    Fields _inputFields;\n    ProjectionFactory _projection;\n    AppendCollector _collector;\n    \n    public StateQueryProcessor(String stateId, Fields inputFields, QueryFunction function) {\n        _stateId = stateId;\n        _function = function;\n        _inputFields = inputFields;\n    }\n    \n    @Override\n    public void prepare(Map conf, TopologyContext context, TridentContext tridentContext) {\n        List<Factory> parents = tridentContext.getParentTupleFactories();\n        if(parents.size()!=1) {\n            throw new RuntimeException(\"State query operation can only have one parent\");\n        }\n        _context = tridentContext;\n        _state = (State) context.getTaskData(_stateId);\n        _projection = new ProjectionFactory(parents.get(0), _inputFields);\n        _collector = new AppendCollector(tridentContext);\n        _function.prepare(conf, new TridentOperationContext(context, _projection));\n    }\n\n    @Override\n    public void cleanup() {\n        _function.cleanup();\n    }\n\n    @Override\n    public void startBatch(ProcessorContext processorContext) {\n        processorContext.state[_context.getStateIndex()] =  new BatchState();\n    }\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/nathanmarz/storm/blob/cdb116e942666973bc4eaa0df098d5bab82739e7/storm-core/src/jvm/storm/trident/planner/processor/StateQueryProcessor.java#L36-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: two parents wired to the stateQuery node\njoinNode -> stateQueryNode; s2 -> stateQueryNode;\n// after: join output is the single parent\nStream joined = s1.join(s2, ...);\njoined.stateQuery(stateFactory, fields, queryFunction);","handlingStrategy":"validation","validationCode":"// Java: verify query node has a single parent before topology build\nif (queryNode.getParents().size() != 1) {\n    throw new IllegalArgumentException(\"stateQuery requires exactly one parent stream\");\n}","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["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"],"tags":["trident","state-query","drpc","invalid-wiring"],"backgroundTag":"incompatible-source-type","analyzedSha":"cdb116e942666973bc4eaa0df098d5bab82739e7","analyzedAt":"2026-09-12T14:30:00.714Z","contentChangedAt":"2026-09-12T14:30:00.714Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}