hiero-ledger / hiero-ledger/hiero-consensus-node
Investigate and Fix: `HapiClients has no matching stub!`
- Dominant language
- Java
- Stars
- 406
- Forks
- 226
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 210
Description
In recent e2e testing for [HIP-1299](https://github.com/hiero-ledger/hiero-improvement-proposals/pull/1299), two yahcli operations were attempted that resulted in the following null pointer exception:
```
2025-12-18 17:43:09.192 WARN 221 HapiSpecOperation - 'UploadSystemFile-150' - CustomSpecAssert failed - java.lang.NullPointerException: HapiClients has no matching stub!!
java.lang.IllegalStateException: java.lang.NullPointerException: HapiClients has no matching stub!
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.handleExec(CustomSpecAssert.java:51)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.executeHederaOps(CustomSpecAssert.java:31)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.allRunFor(CustomSpecAssert.java:25)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.allRunFor(CustomSpecAssert.java:56)
at com.hedera.services.bdd.spec.utilops.UtilVerbs.lambda$updateSpecialFile$60(UtilVerbs.java:1798)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.submitOp(CustomSpecAssert.java:72)
at com.hedera.services.bdd.spec.HapiSpecOperation.execFor(HapiSpecOperation.java:207)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.handleExec(CustomSpecAssert.java:48)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.executeHederaOps(CustomSpecAssert.java:31)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.allRunFor(CustomSpecAssert.java:25)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.allRunFor(CustomSpecAssert.java:56)
at com.hedera.services.bdd.spec.utilops.SourcedOp.submitOp(SourcedOp.java:19)
at com.hedera.services.bdd.spec.HapiSpecOperation.execFor(HapiSpecOperation.java:207)
at com.hedera.services.bdd.spec.HapiSpec.exec(HapiSpec.java:1006)
at com.hedera.services.bdd.spec.HapiSpec.run(HapiSpec.java:803)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at com.hedera.services.bdd.suites.HapiSuite.runSequentialSpecs(HapiSuite.java:275)
at com.hedera.services.bdd.suites.HapiSuite.runSuite(HapiSuite.java:233)
at com.hedera.services.bdd.suites.HapiSuite.runSuiteSync(HapiSuite.java:205)
at com.hedera.services.yahcli.commands.files.SysFileUploadCommand.call(SysFileUploadCommand.java:106)
at com.hedera.services.yahcli.commands.files.SysFileUploadCommand.call(SysFileUploadCommand.java:14)
at picocli.CommandLine.executeUserObject(CommandLine.java:2031)
at picocli.CommandLine.access$1500(CommandLine.java:148)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2469)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2461)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2423)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2277)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2425)
at picocli.CommandLine.execute(CommandLine.java:2174)
at com.hedera.services.yahcli.Yahcli.main(Yahcli.java:118)
Caused by: java.lang.NullPointerException: HapiClients has no matching stub!
at java.base/java.util.Objects.requireNonNull(Objects.java:259)
at com.hedera.services.bdd.spec.infrastructure.HapiClients.nextStubsFromPool(HapiClients.java:390)
at com.hedera.services.bdd.spec.infrastructure.HapiClients.getFileSvcStub(HapiClients.java:212)
at com.hedera.services.bdd.junit.hedera.utils.GrpcUtils.submit(GrpcUtils.java:133)
at com.hedera.services.bdd.junit.hedera.AbstractGrpcNetwork.submit(AbstractGrpcNetwork.java:70)
at com.hedera.services.bdd.spec.transactions.HapiTxnOp.submitOp(HapiTxnOp.java:229)
at com.hedera.services.bdd.spec.HapiSpecOperation.execFor(HapiSpecOperation.java:207)
at com.hedera.services.bdd.spec.utilops.CustomSpecAssert.handleExec(CustomSpecAssert.java:48)
... 29 more
```
The first command was an attempt to update a node's account ID:
```
$ docker run --interactive --tty --volume $(pwd):/launch gcr.io/hedera-registry/yahcli:0.68 --fixed-fee 100000000 --node-account 8 --network integration --payer 58 -v debug nodes update --accountNum 11 --nodeId 5
```
The second command was an attempt to upload a new jar to the network:
```
docker run --interactive --tty --volume $(pwd):/launch gcr.io/hedera-registry/yahcli:0.68 \
--fixed-fee 100000000 \
--node-account 7 \
--network integration \
--payer 54 \
sysfiles upload software-zip \
--bytes-per-append 5140 \
--appends-per-burst 512
```
This is the yahcli config present during both operations:
```yml
defaultNetwork: localhost
networks:
localhost:
nodes:
- { id: 0, account: 3, ipv4Addr: host.docker.internal }
integration:
shard: 0
realm: 0
nodes:
- { id: 0, account: 3, ipv4Addr: }
- { id: 1, account: 4, ipv4Addr: }
- { id: 2, account: 5, ipv4Addr: }
- { id: 3, account: 6, ipv4Addr: }
```
This ticket is for both diagnosing and fixing this bug.
Contributor guide
Research direction
Start with HapiClients.nextStubsFromPool() and getFileSvcStub(), then follow the calls through GrpcUtils.submit() and the yahcli entry points SysFileUploadCommand and the nodes update operation. Reproduce both documented docker commands and identify why no matching stub is available; done means both operations complete without the HapiClients exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, grpc, java
- Domain
- backend, cli, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100