Use daemon auth for unmanaged restart probes#59439
Conversation
Greptile SummaryThe production change in
Confidence Score: 4/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/cli/daemon-cli/lifecycle.test.ts
Line: 286-310
Comment:
**Test never reaches the new code path — missing `loadConfig` return value setup**
`loadConfig.mockReset()` runs in `beforeEach` (line 153) without a subsequent mock implementation, so `loadConfig()` returns nothing for this test. `readBestEffortConfig()` resolves to a falsy value, `cfg` is falsy in `assertUnmanagedGatewayRestartEnabled`, and the function takes the `{ auth: {} }` fallback — `resolveGatewayProbeAuthSafeWithSecretInputs` is never called. The assertion checking `auth.token` from the service command env will fail because `probeGateway` actually receives `auth: {}`.
The fix is to configure `loadConfig` to return an object in this test (e.g. via `loadConfig.mockImplementation(() => ({}))`) before calling `runDaemonRestart`, so that `cfg` is truthy and the merged-env auth resolution path is actually exercised.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "Use daemon auth for unmanaged restart pr..." | Re-trigger Greptile |
| it("uses service command auth for unmanaged restart probes when shell env is unset", async () => { | ||
| findVerifiedGatewayListenerPidsOnPortSync.mockReturnValue([4200]); | ||
| mockUnmanagedRestart({ runPostRestartCheck: true }); | ||
|
|
||
| delete process.env.OPENCLAW_GATEWAY_TOKEN; | ||
| delete process.env.OPENCLAW_GATEWAY_PASSWORD; | ||
|
|
||
| service.readCommand.mockResolvedValue({ | ||
| programArguments: ["openclaw", "gateway", "--port", "18789"], | ||
| environment: { | ||
| OPENCLAW_GATEWAY_TOKEN: " service-token ", | ||
| }, | ||
| }); | ||
|
|
||
| await runDaemonRestart({ json: true }); | ||
|
|
||
| expect(probeGateway).toHaveBeenCalledWith( | ||
| expect.objectContaining({ | ||
| auth: { | ||
| token: "service-token", | ||
| password: undefined, | ||
| }, | ||
| }), | ||
| ); | ||
| }); |
There was a problem hiding this comment.
Test never reaches the new code path — missing
loadConfig return value setup
loadConfig.mockReset() runs in beforeEach (line 153) without a subsequent mock implementation, so loadConfig() returns nothing for this test. readBestEffortConfig() resolves to a falsy value, cfg is falsy in assertUnmanagedGatewayRestartEnabled, and the function takes the { auth: {} } fallback — resolveGatewayProbeAuthSafeWithSecretInputs is never called. The assertion checking auth.token from the service command env will fail because probeGateway actually receives auth: {}.
The fix is to configure loadConfig to return an object in this test (e.g. via loadConfig.mockImplementation(() => ({}))) before calling runDaemonRestart, so that cfg is truthy and the merged-env auth resolution path is actually exercised.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cli/daemon-cli/lifecycle.test.ts
Line: 286-310
Comment:
**Test never reaches the new code path — missing `loadConfig` return value setup**
`loadConfig.mockReset()` runs in `beforeEach` (line 153) without a subsequent mock implementation, so `loadConfig()` returns nothing for this test. `readBestEffortConfig()` resolves to a falsy value, `cfg` is falsy in `assertUnmanagedGatewayRestartEnabled`, and the function takes the `{ auth: {} }` fallback — `resolveGatewayProbeAuthSafeWithSecretInputs` is never called. The assertion checking `auth.token` from the service command env will fail because `probeGateway` actually receives `auth: {}`.
The fix is to configure `loadConfig` to return an object in this test (e.g. via `loadConfig.mockImplementation(() => ({}))`) before calling `runDaemonRestart`, so that `cfg` is truthy and the merged-env auth resolution path is actually exercised.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1dfb403370
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const tlsEnabled = !!cfg?.gateway?.tls?.enabled; | ||
| const scheme = tlsEnabled ? "wss" : "ws"; | ||
| const probeAuth = cfg | ||
| ? await resolveGatewayProbeAuthSafeWithSecretInputs({ |
There was a problem hiding this comment.
Catch probe-auth resolution failures in unmanaged restart check
This awaited auth-resolution call can throw non-GatewaySecretRefUnavailableError exceptions (for example SecretProviderResolutionError from a failing SecretRef backend), and the exception currently bubbles out of assertUnmanagedGatewayRestartEnabled. In that scenario runDaemonRestart exits before signaling the unmanaged gateway PID, even though this preflight is otherwise best-effort (probeGateway failures are swallowed). This turns transient secret-provider issues into hard restart failures for unmanaged deployments.
Useful? React with 👍 / 👎.
|
The current |
|
This is superseded by #72405, which has landed as the canonical ProjectClownfish fix path for this cluster. Closing this now that the validated fix is merged. If this still reproduces on current main with a different path, reply here and we can reopen or split it back out. |
Resubmitting after reducing my active PR queue below the repo limit. This is the same focused fix, with the existing lifecycle test passing locally.
Summary
Use daemon/service-command auth when probing unmanaged gateway restarts instead of relying only on the current shell environment.
What changed
src/cli/daemon-cli/lifecycle.tsprocess.envfor probe auth resolutionresolveGatewayProbeAuthSafeWithSecretInputs(...)when config is availableWhy
The unmanaged restart probe path was previously reading only:
OPENCLAW_GATEWAY_TOKENOPENCLAW_GATEWAY_PASSWORDfrom the current shell environment.
That could make restart health checks miss valid daemon auth that was present in the service command environment, even though other daemon-status paths already reason about daemon/service environment separately.
This change makes unmanaged restart probing use the daemon-side auth view instead of only the caller shell environment.
Scope boundary
This PR does not change the broader daemon status flow or the probe auth resolver itself. It only updates the unmanaged restart probe path in
lifecycle.tsto use the daemon/service-command environment when resolving auth.Manual verification
src/cli/daemon-cli/lifecycle.test.tspnpm vitest run src/cli/daemon-cli/lifecycle.test.ts