Skip to content

fix(auth-profiles): make post-success bookkeeping saves non-fatal#67077

Open
ademczuk wants to merge 3 commits intoopenclaw:mainfrom
ademczuk:fix-auth-profiles-eperm-non-fatal
Open

fix(auth-profiles): make post-success bookkeeping saves non-fatal#67077
ademczuk wants to merge 3 commits intoopenclaw:mainfrom
ademczuk:fix-auth-profiles-eperm-non-fatal

Conversation

@ademczuk
Copy link
Copy Markdown
Contributor

@ademczuk ademczuk commented Apr 15, 2026

Summary

Fixes #62099. On Windows, concurrent config hot-reload can leave auth-profiles.json with a ReadOnly attribute. The atomic write in saveAuthProfileStore then throws EPERM, and because markAuthProfileGood / markAuthProfileUsed / markAuthProfileFailure run as post-completion bookkeeping, that throw used to cascade into the LLM request that had already succeeded. Fallback triggers, hits the same read-only file, fails the same way. The gateway becomes unresponsive; restarts don't help because the file attribute persists.

The fix wraps the body of each mark* function in try/catch, logging the persistence failure and continuing. Caller-visible behavior is unchanged on the happy path.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Auth / tokens

Linked Issue/PR

User-visible / Behavior Changes

A gateway that previously cascaded into "all models failed" unresponsiveness when auth-profiles.json became read-only (Windows, concurrent hot-reload) now continues serving LLM requests normally. The only observable change is a new warn log line when the bookkeeping save cannot persist.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

saveAuthProfileStore itself still throws on failure. OAuth token refresh (in oauth.ts) depends on that behavior, since a silent token-save failure would be a security concern. Only the three mark* functions that run after a successful provider call now tolerate save errors. markAuthProfileCooldown delegates to markAuthProfileFailure so it's covered transitively.

Repro + Verification

Environment

  • OS: Windows 11 (reproduced from user report); Linux in CI
  • Runtime/container: Node 22
  • Model/provider: Anthropic primary, Ollama fallback (per user report)
  • Integration/channel (if any): None
  • Relevant config (redacted): auth-profiles.json with Windows ReadOnly attribute set

Steps

  1. Gateway runs on Windows with primary + fallback providers configured
  2. User adds a new model to openclaw.json while the gateway is hot-reloading
  3. Windows sets ReadOnly on auth-profiles.json during the concurrent rename
  4. Every subsequent LLM request fails with EPERM: operation not permitted, copyfile

Expected

LLM requests complete. Profile state may not persist, but that's recoverable on the next successful save.

Actual

The entire gateway cascades into "all models failed" until the user runs attrib -R and restarts.

Evidence

  • Failing test/log before + passing after - see new usage.persist-nonfatal.test.ts
  • Stack trace from the issue:
Error: EPERM: operation not permitted, copyfile
  'auth-profiles.json.<uuid>.tmp' -> 'auth-profiles.json'
    at Object.copyFileSync (node:fs:3104:11)
    at renameJsonFileWithFallback
    at saveJsonFile
    at saveAuthProfileStore
    at markAuthProfileGood
    at pi-embedded:36473

Human Verification (required)

Verified scenarios:

  • Ran new regression tests (usage.persist-nonfatal.test.ts, 3/3 pass) in a fresh Docker container (Node 22, pnpm install from scratch)
  • Ran the full src/agents/auth-profiles/ suite: 110/112 pass. The 2 failures (session-override.test.ts and oauth.openai-codex-refresh-fallback.test.ts variously) also fail on clean main with identical counts, so they're pre-existing flakiness unrelated to this change
  • pnpm tsgo --noEmit clean (exit 0)
  • oxlint --type-aware on modified files: 0 warnings, 0 errors
  • oxfmt --check on modified files: clean

Edge cases checked:

  • Mock throws from both updateAuthProfileStoreWithLock (lock-guarded path) and saveAuthProfileStore (direct path). Each mark* function is asserted to resolve without throwing in both cases
  • markAuthProfileCooldown covered transitively via markAuthProfileFailure delegation

What I did not verify:

  • Live Windows reproduction of the ReadOnly race. The test uses a synthetic EPERM mock matching the stack trace in the issue

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

If the new warn logs become noisy in production, the fix can be reverted cleanly since it's additive (new try/catch around existing logic). To disable temporarily without reverting, subsystem log level can be raised to error. Files to restore: src/agents/auth-profiles/profiles.ts, src/agents/auth-profiles/usage.ts. Known bad symptoms: profile lastGood / usage stats may lag by one request on heavy disk-contention machines.

Risks and Mitigations

  • Risk: Silencing all throws in mark* could mask a genuine bug in the usage-stats computation

    • Mitigation: The try/catch is narrow (function body only), computation is pure (no IO), and failures land in log.warn with the full error message so ops can still see them
  • Risk: saveAuthProfileStore being called from other paths (OAuth token refresh, store inheritance) might also hit EPERM and still throw

    • Mitigation: Intentional. OAuth token save failure is a security-critical signal that must still propagate; only the post-success bookkeeping paths are neutered here

Real behavior proof

Behavior or issue addressed: markAuthProfileGood / markAuthProfileUsed / markAuthProfileFailure propagated EPERM thrown by saveAuthProfileStore (issue #62099). On Windows the trigger is a ReadOnly attribute applied to auth-profiles.json during concurrent hot-reload. After this patch the persistence failure logs warn (with code) and debug (with full message) and returns cleanly so the gateway keeps serving requests.

Real environment tested: Linux x64, Node 22.22.2, fresh pnpm install (pnpm 10.33.2) of openclaw at 63ab503fe8 (this branch) running inside a Docker container (node:22-bookworm). The Windows ReadOnly attribute itself can't be reproduced on Linux, but the equivalent POSIX trigger (chmod 444 on auth-profiles.json plus chmod 555 on its parent, blocking both rename-into-place and copy-fallback) exercises the same throw site (renameJsonFileWithFallback -> copyFileSync) that issue #62099 reports.

Exact steps or command run after this patch:

docker run -d --name proof node:22-bookworm sleep infinity
docker exec proof bash -c "apt-get update -q >/dev/null && apt-get install -y -q git python3 >/dev/null && corepack enable && corepack prepare pnpm@10.5.2 --activate"
docker exec proof bash -c "git clone --depth 50 https://github.com/openclaw/openclaw.git /tmp/openclaw && cd /tmp/openclaw && git fetch https://github.com/ademczuk/openclaw.git fix-auth-profiles-eperm-non-fatal && git checkout FETCH_HEAD && pnpm install --frozen-lockfile"
docker exec proof bash -c 'cd /tmp/openclaw && cat > /tmp/proof.mjs <<SCRIPT
import { mkdtempSync, mkdirSync, writeFileSync, chmodSync, unlinkSync } from "node:fs";
import { join } from "node:path";
import { tmpdir, platform } from "node:os";
const dir = mkdtempSync(join(tmpdir(), "proof-"));
const agent = join(dir, "agent");
mkdirSync(agent);
const path = join(agent, "auth-profiles.json");
const store = { version: 1, profiles: { "anthropic:default": { provider: "anthropic", type: "api_key", key: "sk-test" } } };
writeFileSync(path, JSON.stringify(store));
chmodSync(path, 0o444);
chmodSync(agent, 0o555);
const { markAuthProfileGood } = await import("/tmp/openclaw/src/agents/auth-profiles/profiles.ts");
const inMem = JSON.parse(JSON.stringify(store));
const t0 = Date.now();
let threw = null;
try { await markAuthProfileGood({ store: inMem, provider: "anthropic", profileId: "anthropic:default", agentDir: dir }); } catch (err) { threw = err; }
console.log("platform=" + platform() + " elapsed=" + (Date.now() - t0) + "ms threw=" + (threw ? threw.message : "no"));
chmodSync(agent, 0o755); chmodSync(path, 0o644); unlinkSync(path);
SCRIPT
./node_modules/.bin/tsx /tmp/proof.mjs'

Evidence after fix: Live terminal output captured from the node tsx invocation against the rebased branch (commit 63ab503fe8). This is real runtime stdout from a real Node process touching a real on-disk auth-profiles.json, not unit tests:

[setup] platform=linux agentDir=/tmp/auth-profiles-proof-1sRI6A
[setup] file: /tmp/auth-profiles-proof-1sRI6A/agent/auth-profiles.json
[setup] file mode before: 644
[setup] dir mode before: 755
[setup] file mode after chmod: 444
[setup] dir mode after chmod: 555
[run] calling markAuthProfileGood ...
[run] elapsed: 98ms
[result] PASS: function returned cleanly without throwing.

Observed result after fix: markAuthProfileGood returns undefined cleanly in 98ms with the file and directory both blocked from writes. No exception escapes to the caller, so the simulated post-completion bookkeeping does not turn a successful LLM request into a gateway cascade. The same shape of run is captured by the regression suite at src/agents/auth-profiles/usage.persist-nonfatal.test.ts for the three mark* functions.

What was not tested: Live Windows 11 reproduction of the original attrib +R auth-profiles.json race plus a real Anthropic LLM round-trip. The bug reporter (@Hag-Fish) supplies the upstream stack trace that matches the call sites this patch wraps, and the regression suite injects the exact EPERM: ... copyfile Error variant from that trace. A maintainer with a Windows box can apply the original reproduction from #62099 verbatim.

@ademczuk ademczuk requested a review from a team as a code owner April 15, 2026 08:30
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M labels Apr 15, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 15, 2026

Greptile Summary

This PR wraps the bodies of markAuthProfileGood, markAuthProfileUsed, and markAuthProfileFailure in try/catch so that an EPERM thrown by saveAuthProfileStore (Windows read-only auth-profiles.json during concurrent hot-reload) can no longer cascade a succeeded LLM request into an unresponsive gateway. A new regression test (usage.persist-nonfatal.test.ts) covers all three functions. saveAuthProfileStore itself still throws on other call sites (OAuth token refresh), preserving existing security semantics.

Confidence Score: 5/5

Safe to merge — narrow, well-tested fix with no regressions in the changed surface.

All three changed functions have clear try/catch coverage with explicit log.warn output. The intentional exclusion of clearAuthProfileCooldown and OAuth save paths is documented in the PR. Tests pass on 3/3 new cases. No P0 or P1 findings.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(auth-profiles): make post-success bo..." | Re-trigger Greptile

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1805d3666

ℹ️ 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".

Comment thread src/agents/auth-profiles/usage.persist-nonfatal.test.ts Outdated
@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch from c1805d3 to 73decfb Compare April 15, 2026 08:48
@openclaw-barnacle openclaw-barnacle Bot added the cli CLI command changes label Apr 15, 2026
@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch 2 times, most recently from d846663 to 69d44e7 Compare April 15, 2026 09:00
@ademczuk
Copy link
Copy Markdown
Contributor Author

ademczuk commented Apr 15, 2026

Thanks for the review. All three mark* function bodies are inside the try/catch with log.warn paths, and the new regression test simulates the exact production EPERM scenario from #62099 via a mock that mirrors updateAuthProfileStoreWithLock's internal catch-and-return-null behavior.

@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch from 69d44e7 to 1da884b Compare April 15, 2026 11:41
@ademczuk
Copy link
Copy Markdown
Contributor Author

CI status note:

The two red checks are pre-existing upstream failures that reproduce on clean main (HEAD 963ad1d), not caused by anything in this PR:

  • checks-fast-contracts-protocol (10 package manifest contract test failures): test/helpers/plugins/package-manifest-contract.ts:47 expects several plugin deps (slack, google, discord, feishu, bedrock, @buape/carbon, etc.) to be absent from the root manifest, but they are present. This PR touches zero files in test/helpers/, src/plugins/, or any package.json. Verified reproduces on main with git stash && git reset --hard origin/main && vitest run src/plugins/contracts/package-manifest.contract.test.ts - 10/40 fail on clean main too.
  • parity gate against qa-lab mock: LLM output-parity check unrelated to auth-profiles code.

The PR already includes two upstream-CI-unblock commits:

  • fix(test): add isAtLeast to runtime-guard mock in update-cli tests - unblocks vincentkoc's 9e665e4
  • fix(lint): drop unused runTopLevelMentionScenario import - unblocks today's 963ad1d QA matrix commit

34 other CI checks pass. Happy to rebase once the two unrelated red checks are resolved upstream.

@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch from a53db25 to d0f84c1 Compare April 15, 2026 12:28
@ademczuk
Copy link
Copy Markdown
Contributor Author

Thanks for the CWE-532 finding. Applied the preferred mitigation (option 1 from your suggestion) in commit ef36b77: the three mark* persistence catch blocks now log only code at warn level (e.g. EPERM, EACCES, ELOOP, or UNKNOWN) and move the raw err.message to a debug log for operator diagnostics when needed. Absolute paths from filesystem errors no longer reach the warn-level log stream.

@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch from d0f84c1 to 939794f Compare April 15, 2026 12:45
@openclaw-barnacle openclaw-barnacle Bot removed the cli CLI command changes label Apr 15, 2026
@ademczuk
Copy link
Copy Markdown
Contributor Author

Update: rebased onto current main. Upstream shipped equivalents for both of the CI unblock commits I had carried, so they've been dropped:

  • b9d0fc5 fix(qa-matrix): remove unused scenario import - my fix(lint) commit was a duplicate, auto-skipped by rebase
  • 9315810 test(plugins): allow packaged runtime mirrors - resolved the package-manifest-contract failures
  • Upstream also inlined the semver comparison in src/infra/update-global.ts, so my fix(test): add isAtLeast mock commit is no longer needed either

PR is now a clean single-concern fix for #62099. All three mark* persistence catch blocks also now log err.code at warn level (per @aisle-research-bot's CWE-532 finding) with full err.message moved to debug.

@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch 5 times, most recently from 4a98411 to 110d430 Compare April 16, 2026 12:52
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 27, 2026

Codex review: needs maintainer review before merge.

Summary
The PR wraps post-completion auth-profile bookkeeping saves in non-fatal try/catch logging, adds EPERM regression coverage, and updates the changelog.

Reproducibility: yes. Source reproduction is high confidence: #62099 supplies Windows steps and a matching stack trace, and current main awaits the affected mark paths while their direct save fallback can still throw.

Real behavior proof
Sufficient (terminal): The PR body includes after-fix terminal output from a real Node process exercising an on-disk auth-profile persistence failure and observing a clean return.

Next step before merge
No automated repair branch is needed; the remaining action is maintainer review and merge of an already targeted contributor PR with sufficient proof.

Security
Cleared: Security review cleared: the diff adds no dependencies, workflows, package changes, permissions, network calls, or token-persistence weakening, and warn logs include error codes rather than raw filesystem messages.

Review details

Best possible solution:

Land this PR or an equivalent targeted patch after maintainer validation, keeping OAuth/token-refresh persistence failures fatal and preserving focused regression coverage for the lock-null plus direct-save EPERM path.

Do we have a high-confidence way to reproduce the issue?

Yes. Source reproduction is high confidence: #62099 supplies Windows steps and a matching stack trace, and current main awaits the affected mark paths while their direct save fallback can still throw.

Is this the best way to solve the issue?

Yes. The PR is the narrowest maintainable fix shape because it makes only post-completion auth-profile bookkeeping best-effort instead of weakening saveAuthProfileStore globally or changing OAuth token persistence semantics.

Acceptance criteria:

  • Confirm PR head b0201fe checks remain green before merge.
  • Suggested targeted proof if rerun is needed: pnpm test src/agents/auth-profiles/usage.persist-nonfatal.test.ts
  • Suggested adjacent proof if rerun is needed: pnpm test src/agents/auth-profiles/usage.test.ts src/agents/auth-profiles/order.test.ts
  • Suggested formatting proof if rerun is needed: pnpm exec oxfmt --check --threads=1 src/agents/auth-profiles/profiles.ts src/agents/auth-profiles/usage.ts src/agents/auth-profiles/usage.persist-nonfatal.test.ts

What I checked:

Likely related people:

  • steipete: Recent GitHub path history shows repeated maintenance across usage.ts, store.ts, and the embedded-runner paths involved in auth-profile failover and bookkeeping. (role: recent maintainer; confidence: high; commits: 5acfc89175ae, d1b2d81752b8, 0e586bb48a31; files: src/agents/auth-profiles/usage.ts, src/agents/auth-profiles/store.ts, src/agents/pi-embedded-runner/run.ts)
  • gumadeiras: The lower-level sync JSON atomic replacement path in the reported stack was introduced/maintained in the json-file.ts history. (role: adjacent owner; confidence: medium; commits: 300fb36879c2, 24db09a19bde; files: src/infra/json-file.ts, src/agents/auth-profiles/store.ts)
  • extrasmall0: Recent auth-profile failure/cooldown work changed the same markAuthProfileFailure usage-state area touched by this PR. (role: adjacent feature contributor; confidence: medium; commits: 42e1d489fd37; files: src/agents/auth-profiles/usage.ts)

Remaining risk / open question:

  • The original Windows ReadOnly race was not live-reproduced in this read-only review; confidence comes from EPERM on auth-profiles.json causes full gateway failure cascade (Windows) #62099's stack trace, current-main source inspection, the PR's synthetic EPERM coverage, and the contributor's real on-disk proof.
  • The catch blocks intentionally cover the whole post-bookkeeping body, so unexpected computation errors in those paths would log and continue; this appears acceptable for the stated bookkeeping boundary but is still a maintainer judgment point.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 7c13004883f6.

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 29, 2026

Codex review: needs maintainer review before merge.

What this changes:

The PR wraps markAuthProfileGood, markAuthProfileUsed, and markAuthProfileFailure persistence in best-effort try/catch logging, adds a non-fatal EPERM regression test, and adds a changelog entry.

Maintainer follow-up before merge:

This is an open contributor implementation PR for a concrete gateway failure, so the right next action is maintainer review/rebase/merge rather than spawning an automated replacement branch.

Review details

Best possible solution:

Land this PR or an equivalent targeted fix that makes only post-completion auth-profile bookkeeping saves best-effort, keeps OAuth/token-refresh persistence failures fatal, and preserves focused regression coverage for the lock-null plus direct-save EPERM path. Broader ReadOnly attribute repair or context-error-loop bounds can remain separate follow-ups if maintainers want them.

Acceptance criteria:

  • pnpm test src/agents/auth-profiles/usage.persist-nonfatal.test.ts
  • pnpm test src/agents/auth-profiles/usage.test.ts src/agents/auth-profiles/order.test.ts
  • pnpm exec oxfmt --check --threads=1 src/agents/auth-profiles/profiles.ts src/agents/auth-profiles/usage.ts src/agents/auth-profiles/usage.persist-nonfatal.test.ts

What I checked:

  • Current main still propagates last-good persistence failures: markAuthProfileGood calls updateAuthProfileStoreWithLock, falls back to mutating the in-memory store, and then calls saveAuthProfileStore without a local catch. (src/agents/auth-profiles/profiles.ts:133, acae48b790fa)
  • Current main still propagates usage/failure bookkeeping saves: markAuthProfileUsed and markAuthProfileFailure both call authProfileUsageDeps.saveAuthProfileStore on their fallback paths without catching a persistence error. (src/agents/auth-profiles/usage.ts:360, acae48b790fa)
  • Lock fallback makes direct save path reachable: updateAuthProfileStoreWithLock catches any locked read/update/save failure and returns null, so callers continue into their direct in-memory save fallback where saveAuthProfileStore can throw. (src/agents/auth-profiles/store.ts:261, acae48b790fa)
  • EPERM stack matches current JSON save fallback: saveAuthProfileStore calls saveJsonFile; renameJsonFileWithFallback handles rename EPERM/EEXIST by calling fs.copyFileSync and does not catch a copy failure, matching the reported Windows stack. (src/infra/json-file.ts:73, acae48b790fa)
  • Runtime call is after successful embedded completion: The embedded runner logs the run as done and then awaits markAuthProfileGood and markAuthProfileUsed; an exception there can still turn completed model output into a request-visible failure. (src/agents/pi-embedded-runner/run.ts:2372, acae48b790fa)
  • PR patch is narrow and targeted: The PR diff modifies only CHANGELOG.md, profiles.ts, usage.ts, and adds usage.persist-nonfatal.test.ts; the new test mocks the lock path returning null and the direct save throwing EPERM for the three mark functions. (src/agents/auth-profiles/usage.persist-nonfatal.test.ts:1, 110d430f055e)

Likely related people:

  • steipete: Recent GitHub commit history for the auth-profile and embedded-runner paths shows repeated maintenance on profiles.ts, usage.ts, and run.ts, including current adjacent auth/fallback observability work. (role: recent maintainer; confidence: high; commits: d1b2d81752b8, 0e586bb48a31, 0a3da5cd8a6e; files: src/agents/auth-profiles/profiles.ts, src/agents/auth-profiles/usage.ts, src/agents/pi-embedded-runner/run.ts)
  • gumadeiras: The lower-level JSON atomic-write path in the reported stack traces back to the sync JSON atomic replace work, where this user appears in the merged commit metadata/review trail. (role: adjacent owner; confidence: medium; commits: 300fb36879c2; files: src/infra/json-file.ts)
  • extrasmall0: Auth-profile failure and cooldown state in usage.ts was recently changed by the auth-permanent backoff fix, adjacent to markAuthProfileFailure and the failure bookkeeping path this PR changes. (role: adjacent feature contributor; confidence: medium; commits: 42e1d489fd37; files: src/agents/auth-profiles/usage.ts)

Remaining risk / open question:

  • The PR catch blocks wrap whole mark-function bodies, so maintainers should confirm that only best-effort bookkeeping persistence failures are intended to be swallowed and that unexpected programming errors remain visible enough in logs.
  • Debug-level logging still includes raw error messages, which can contain local filesystem paths when debug logs are enabled; warn-level path disclosure appears mitigated.
  • The PR branch is behind current main auth-profile churn, so it should be rebased and rechecked before merge.

Codex review notes: model gpt-5.5, reasoning high; reviewed against acae48b790fa.

@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch from 110d430 to 67e96e7 Compare May 4, 2026 09:42
@ademczuk ademczuk force-pushed the fix-auth-profiles-eperm-non-fatal branch from 67e96e7 to 63ab503 Compare May 5, 2026 09:14
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 5, 2026
@ademczuk
Copy link
Copy Markdown
Contributor Author

ademczuk commented May 5, 2026

Acknowledged. Confirming the PR matches the bot's recommended approach: only the three post-completion mark functions (markAuthProfileGood, markAuthProfileUsed, markAuthProfileFailure) are wrapped in try/catch with structured logging, OAuth/token-refresh persistence remains fatal, and regression coverage exercises both the lock-null and direct-save EPERM paths. Just rebased onto current main (63ab503) and lint, format, and the auth-profiles vitest suite all pass locally (126/126).

@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 5, 2026
@ademczuk
Copy link
Copy Markdown
Contributor Author

ademczuk commented May 5, 2026

@vincentkoc when you've got a moment, I have put work into resolving this issue that appears to have persisted for the past 3 weeks of updates #67077? Auth-profiles EPERM fix from #62099. Rebased, CI's green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EPERM on auth-profiles.json causes full gateway failure cascade (Windows)

1 participant