`ii` ICP feature panics the server during instance creation — unusable from PocketIC-JS (no create-with-gateway option)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 35
- Forks
- 6
- Avg merge
- 9m
- Merged PRs (30d)
- 1
Description
Enabling the ii ICP feature makes the server panic while creating the instance. The client sees only TypeError: fetch failed / SocketError: other side closed, and because the instance never comes up there is nothing in a per-instance log to look at — which is what made this hard to diagnose from the client side.
Versions
- PocketIC-JS (
@dfinity/pic) 0.22.0 (source: https://github.com/dfinity/pic-js) pocket-ic-server14.0.0 (the binary shipped with that package)- macOS arm64
Root cause
Running the server with showRuntimeLogs: true surfaces it:
thread 'tokio-runtime-worker' panicked at rs/pocket_ic_server/src/pocket_ic.rs:2224:46:
The HTTP gateway is supposed to be created if the `ii` ICP feature is specified.
thread 'tokio-runtime-worker' panicked at rs/pocket_ic_server/src/state_api/state.rs:627:14:
Failed to create PocketIC instance: JoinError::Panic(Id(21),
"The HTTP gateway is supposed to be created if the `ii` ICP feature is specified.", ...)
So the server requires an HTTP gateway to exist at instance-creation time when ii is requested.
Why that makes it unusable from PocketIC-JS
PocketIC-JS creates the gateway in a separate, later call — pic.makeLive(). And CreateInstanceOptions has no option to create an instance with a gateway:
nns, sns, ii, fiduciary, bitcoin, system, application, verifiedApplication,
processingTimeoutMs, ingressMaxRetries, icpConfig, icpFeatures,
disableIngressValidation
So the precondition cannot be met before creation, and creation is what panics. There is no workaround from JS as far as I can tell — makeLive() is unreachable because the instance does not exist yet.
Minimal reproduction
import { PocketIcServer, PocketIc, IcpFeaturesConfig } from '@dfinity/pic';
const server = await PocketIcServer.start({ showRuntimeLogs: true });
await PocketIc.create(server.getUrl(), {
icpFeatures: { ii: IcpFeaturesConfig.DefaultConfig },
});
// → TypeError: fetch failed (server panicked, see logs above)
It is unconditional — not a subnet or feature-combination problem
I initially assumed a conflict with our explicit ii subnet, or with the II canisters being split across backend/frontend in some versions. Both wrong. Every one of these fails identically:
| Config | Result |
|---|---|
{ ii } alone, default subnets |
FAIL |
{ ii } + explicit ii subnet |
FAIL |
{ ii } + explicit nns subnet |
FAIL |
{ ii, cycles_minting } |
FAIL |
{ icp_token, cycles_minting, cycles_token, ii } + 4 explicit subnets |
FAIL |
same as above without ii |
PASS |
Note the docs for IcpFeatures say "The subnets to which the corresponding system canisters are deployed must be empty" — that is satisfied in the first case (a fresh instance with default subnets) and it still panics.
Suggested fixes
Two separable things, and the first is worth doing regardless:
-
Server: return an error instead of panicking. A panic in the instance-creation task surfaces to the client as an opaque transport failure with no diagnostic. A
400/4xxsaying "theiifeature requires an HTTP gateway" would have turned an afternoon into a minute. This is the higher-value fix even if the precondition itself stays. -
Make the feature reachable. Either the server creates the gateway itself when
iiis requested (the panic message reads as though that is the intent — "is supposed to be created"), or PocketIC-JS gains a create-with-gateway option so the precondition can be satisfied. Right now the two sides disagree about whose job it is, and the feature falls through the gap.
Happy to test a fix — this is directly in the way of something we want (below).
What we are trying to do
A fully local end-to-end test of a Stripe→cycles gateway: browser drives the real UI, signs in with Internet Identity, an order is created, a real signed Stripe webhook arrives over the HTTP gateway, and the CMC mints and delivers cycles.
Everything except sign-in already works in PocketIC — real ICP ledger, real CMC, real cycles ledger, makeLive() serving the webhook route over genuine HTTP, plus outage injection by stopping the NNS canisters. Mainnet II works too, but the real II UI needs a real passkey, which a headless browser cannot produce; a local II mocks that, which is why this feature is the blocker for automating the last step.
Related feature requests filed separately so this bug stays actionable on its own.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with showRuntimeLogs: true, then inspect rs/pocket_ic_server/src/pocket_ic.rs around line 2224 and rs/pocket_ic_server/src/state_api/state.rs around line 627. Trace the PocketIC-JS create and makeLive() flow described in the issue; done means ii instance creation no longer becomes an opaque transport failure and the feature has a viable gateway-creation path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, typescript
- Domain
- api, backend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100