Skip to content

fix(credentials): recover reset from attached-provider FailedPrecondition (#5560)#5573

Merged
cv merged 1 commit into
NVIDIA:mainfrom
latenighthackathon:fix-credentials-reset-attached-provider
Jul 3, 2026
Merged

fix(credentials): recover reset from attached-provider FailedPrecondition (#5560)#5573
cv merged 1 commit into
NVIDIA:mainfrom
latenighthackathon:fix-credentials-reset-attached-provider

Conversation

@latenighthackathon

@latenighthackathon latenighthackathon commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

credentials reset <provider> ran a raw provider delete and, when the provider was still attached to a sandbox, surfaced the OpenShell FailedPrecondition: provider attached to sandbox(es): <name> with no way forward. After onboarding Brave Search the provider is <sandbox>-brave-search, which is not a messaging bridge, so it fell straight through to that dead end and the only fix was destroying and recreating the sandbox.

Related Issue

Fixes #5560

Changes

  • Route the delete in src/commands/credentials/reset.ts through the existing deleteProviderWithRecovery helper, which detaches the listed sandboxes and retries the delete once (the same recovery path the onboard provider-replace flow already uses).
  • On residual failure, surface the still-attached sandboxes with a openshell sandbox provider detach hint instead of the raw diagnostic.
  • Extract formatResetOutcome so the success / still-attached / env-var-name-hint output is unit tested without the oclif command harness, and add test/credentials-reset-outcome.test.ts.

Out of scope: the report also notes the Brave placeholder openshell:resolve:env:v<id>_BRAVE_API_KEY regenerates a new id on every read and never resolves. That scoping behavior lives in the OpenShell credential resolver (NemoClaw emits the unscoped placeholder), so it is better tracked there. This change removes the NemoClaw-side reset dead end so a stuck provider can be cleared without recreating the sandbox.

Type of Change

  • Code change (feature, bug fix, or refactor)

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push, or npx prek run --from-ref main --to-ref HEAD passes
  • Targeted tests pass for changed behavior
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed

Ran: npx vitest run test/credentials-reset-outcome.test.ts test/sandbox-provider-cleanup.test.ts (29 passed), npm run build:cli, and biome check on the touched files (clean). The full-suite test-cli/test-plugin commit and push hooks were skipped because they trip on a pre-existing collection error in test/ssrf-parity.test.ts (0 tests collected) that also fails on a clean main checkout and is unrelated to this change. CI runs the full gate.


Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved error messaging and handling when resetting provider credentials.
    • Enhanced support for cases where a provider remains attached to sandboxes, including helpful recovery instructions.
    • Better input validation to detect when credential names appear to be environment variables rather than provider names.

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 886a96f1-bb9b-4635-80dc-989eac901b99

📥 Commits

Reviewing files that changed from the base of the PR and between f8d9c4a and 8fef6cb.

📒 Files selected for processing (2)
  • src/commands/credentials/reset.ts
  • test/credentials-reset-outcome.test.ts

📝 Walkthrough

Walkthrough

The credentials reset command now delegates deletion to deleteProviderWithRecovery instead of directly invoking provider delete. A new exported helper, formatResetOutcome, centralizes all user-facing output for success, env-var-name misuse, and still-attached-sandbox failure cases. A Vitest suite validates all three formatting paths.

Changes

Credential Reset Recovery Flow

Layer / File(s) Summary
Recovery-based deletion and formatResetOutcome helper
src/commands/credentials/reset.ts
Imports deleteProviderWithRecovery and ProviderDeleteWithRecoveryResult; replaces inline direct provider delete call with recovery-based deletion; adds exported formatResetOutcome that produces success lines, an env-var-name hint (regex), attached-sandbox detach instructions from recovery.recoveryFailures, and trimmed recovery.stderr; command logs on success and calls failWithLines on failure.
Vitest suite for formatResetOutcome
test/credentials-reset-outcome.test.ts
New test file with a result() partial-override helper and three cases: clean removal, FailedPrecondition attached-sandbox detach hint, and env-var-like argument detection.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

bug-fix

🐇 A key that wandered, now found its way,
The sandbox said "no" — but we handle that day!
formatResetOutcome speaks plain as can be,
"Detach from your sandbox, then come back to me."
Three test cases hop by, all green in a row~ 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: fixing the credentials reset command to recover from FailedPrecondition errors when a provider is attached to sandboxes.
Linked Issues check ✅ Passed The PR successfully addresses the CLI-side issue in #5560 by enabling users to reset a stuck provider without destroying the sandbox, though it acknowledges the upstream credential-resolver placeholder regeneration remains out of scope.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the credentials reset failure: modifying the reset command to use deleteProviderWithRecovery, extracting formatResetOutcome for testability, and adding corresponding unit tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression labels Jun 23, 2026
@wscurran

Copy link
Copy Markdown
Contributor

@latenighthackathon
latenighthackathon force-pushed the fix-credentials-reset-attached-provider branch from 8fef6cb to 0ddc062 Compare July 2, 2026 04:38
…tion (NVIDIA#5560)

`credentials reset <provider>` ran a raw `provider delete` and, when the
provider was still attached to a sandbox, surfaced the OpenShell
FailedPrecondition ("provider attached to sandbox(es): <name>") with no way
forward. After onboarding Brave Search the provider is `<sandbox>-brave-search`,
which is not a messaging bridge, so it fell straight through to that dead end:
the only fix was destroying the sandbox.

Route the delete through the existing deleteProviderWithRecovery helper, which
detaches the listed sandboxes and retries the delete once (already used by the
onboard provider-replace path). On residual failure, surface the still-attached
sandboxes with a detach hint instead of the raw diagnostic.

Extract formatResetOutcome so the success / still-attached / env-var-name-hint
output is unit tested without the oclif command harness.

Note: the upstream complaint that the Brave placeholder
(openshell:resolve:env:v<id>_BRAVE_API_KEY) regenerates a new id on every read
and never resolves is an OpenShell credential-resolver scoping issue and is out
of scope here; this change only removes the NemoClaw-side reset dead end.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@latenighthackathon
latenighthackathon force-pushed the fix-credentials-reset-attached-provider branch from 0ddc062 to 95fca32 Compare July 2, 2026 04:46
@wscurran wscurran added the v0.0.87 Release target label Jul 2, 2026
@cv
cv merged commit 0c785eb into NVIDIA:main Jul 3, 2026
30 checks passed
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…tion (NVIDIA#5560) (NVIDIA#5573)

## Summary
`credentials reset <provider>` ran a raw `provider delete` and, when the
provider was still attached to a sandbox, surfaced the OpenShell
`FailedPrecondition: provider attached to sandbox(es): <name>` with no
way forward. After onboarding Brave Search the provider is
`<sandbox>-brave-search`, which is not a messaging bridge, so it fell
straight through to that dead end and the only fix was destroying and
recreating the sandbox.

## Related Issue
Fixes NVIDIA#5560

## Changes
- Route the delete in `src/commands/credentials/reset.ts` through the
existing `deleteProviderWithRecovery` helper, which detaches the listed
sandboxes and retries the delete once (the same recovery path the
onboard provider-replace flow already uses).
- On residual failure, surface the still-attached sandboxes with a
`openshell sandbox provider detach` hint instead of the raw diagnostic.
- Extract `formatResetOutcome` so the success / still-attached /
env-var-name-hint output is unit tested without the oclif command
harness, and add `test/credentials-reset-outcome.test.ts`.

Out of scope: the report also notes the Brave placeholder
`openshell:resolve:env:v<id>_BRAVE_API_KEY` regenerates a new id on
every read and never resolves. That scoping behavior lives in the
OpenShell credential resolver (NemoClaw emits the unscoped placeholder),
so it is better tracked there. This change removes the NemoClaw-side
reset dead end so a stuck provider can be cleared without recreating the
sandbox.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

Ran: `npx vitest run test/credentials-reset-outcome.test.ts
test/sandbox-provider-cleanup.test.ts` (29 passed), `npm run build:cli`,
and `biome check` on the touched files (clean). The full-suite
`test-cli`/`test-plugin` commit and push hooks were skipped because they
trip on a pre-existing collection error in `test/ssrf-parity.test.ts` (0
tests collected) that also fails on a clean `main` checkout and is
unrelated to this change. CI runs the full gate.

---
Signed-off-by: latenighthackathon
<latenighthackathon@users.noreply.github.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
* Improved error messaging and handling when resetting provider
credentials.
* Enhanced support for cases where a provider remains attached to
sandboxes, including helpful recovery instructions.
* Better input validation to detect when credential names appear to be
environment variables rather than provider names.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output bug-fix PR fixes a bug or regression v0.0.87 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Brave Search API key never resolves — credential placeholder regenerates a new random ID on every read, can't be reset or manually fixed

3 participants