Recording + measurement only — no severity asserted, no fix chosen. Found while implementing #14917 (test-layer typecheck for driver-mongodb); unrelated to that card's surface, so filed rather than fixed.
The measurement
packages/services/service-cluster-redis runs its contract test against a test double built for a different major version of the client it doubles.
| fact |
value |
read from |
| the package's runtime dependency |
ioredis: ^6.0.0 |
packages/services/service-cluster-redis/package.json |
| resolved in this workspace |
ioredis@6.0.0 |
node_modules/.pnpm/ioredis@6.0.0/.../package.json |
| its test double |
ioredis-mock: ^8.13.1 (devDependency) |
same manifest |
| that double's declared peer range |
"ioredis": "^5" |
ioredis-mock@8.13.1's own peerDependencies |
pnpm install reports it on a state change:
packages/services/service-cluster-redis
└─┬ ioredis-mock 8.13.1
└── ✕ unmet peer ioredis@^5: found 6.0.0
Why it may be worth more than a peer warning
The consumer is src/redis.contract.test.ts — a file whose stated job is to hold a contract. Its own header says the suites use ioredis-mock "so they execute without a real Redis instance in CI". So the thing standing in for the real client during contract verification is written against ioredis@5's surface, while every non-test path in the package uses ioredis@6.
The seam is also untyped, which removes the one channel that might otherwise have surfaced a divergence:
// @ts-expect-error — ioredis-mock has no published types
import RedisMock from 'ioredis-mock';
⇒ Neither the type checker (suppressed at the import) nor the peer resolver (a warning, not an error) is in a position to report a behavioural difference between ioredis@5 and ioredis@6 that the contract test would then certify as conforming. That is the same shape check:engine-double-contract exists to prevent for driver doubles, one layer over.
Scope of the claim
- ⛔ No claim that any assertion in
redis.contract.test.ts is currently wrong. The suite passes. The claim is about the instrument: a double a major version behind the real client cannot be relied on to disagree with it.
- ⛔ No fix chosen. The routes differ a lot in cost — pin
ioredis back to ^5, find or wait for an ioredis@6-compatible mock, run the contract against a real Redis in CI, or accept and declare the gap — and choosing between them needs someone who knows which ioredis@6 behaviour changes this package actually depends on. That is a measurement nobody has taken.
- ⛔ Nothing about the rest of the cluster stack; only this package's test double.
Dedup
MCP search_issues, one targeted query for the ioredis / unmet-peer / mock-version shape ⇒ 0 results. Control query in the same session (the tsconfig test-exclusion genre) returned 36, so the channel answers and the zero is a reading rather than a silent empty.
Generated by Claude Code
Recording + measurement only — no severity asserted, no fix chosen. Found while implementing #14917 (test-layer typecheck for
driver-mongodb); unrelated to that card's surface, so filed rather than fixed.The measurement
packages/services/service-cluster-redisruns its contract test against a test double built for a different major version of the client it doubles.ioredis: ^6.0.0packages/services/service-cluster-redis/package.jsonioredis@6.0.0node_modules/.pnpm/ioredis@6.0.0/.../package.jsonioredis-mock: ^8.13.1(devDependency)"ioredis": "^5"ioredis-mock@8.13.1's ownpeerDependenciespnpm installreports it on a state change:Why it may be worth more than a peer warning
The consumer is
src/redis.contract.test.ts— a file whose stated job is to hold a contract. Its own header says the suites useioredis-mock"so they execute without a real Redis instance in CI". So the thing standing in for the real client during contract verification is written againstioredis@5's surface, while every non-test path in the package usesioredis@6.The seam is also untyped, which removes the one channel that might otherwise have surfaced a divergence:
⇒ Neither the type checker (suppressed at the import) nor the peer resolver (a warning, not an error) is in a position to report a behavioural difference between
ioredis@5andioredis@6that the contract test would then certify as conforming. That is the same shapecheck:engine-double-contractexists to prevent for driver doubles, one layer over.Scope of the claim
redis.contract.test.tsis currently wrong. The suite passes. The claim is about the instrument: a double a major version behind the real client cannot be relied on to disagree with it.ioredisback to^5, find or wait for anioredis@6-compatible mock, run the contract against a real Redis in CI, or accept and declare the gap — and choosing between them needs someone who knows whichioredis@6behaviour changes this package actually depends on. That is a measurement nobody has taken.Dedup
MCP
search_issues, one targeted query for theioredis/ unmet-peer / mock-version shape ⇒ 0 results. Control query in the same session (thetsconfigtest-exclusion genre) returned 36, so the channel answers and the zero is a reading rather than a silent empty.Generated by Claude Code