Skip to content

fix: claude immutable-thinking resume retry, board-key lock-timeout tolerance, cli-auth/me snapshot - #235

Merged
kkroo merged 3 commits into
masterfrom
omar/claude-resume-auth-fixes
May 31, 2026
Merged

fix: claude immutable-thinking resume retry, board-key lock-timeout tolerance, cli-auth/me snapshot#235
kkroo merged 3 commits into
masterfrom
omar/claude-resume-auth-fixes

Conversation

@kkroo

@kkroo kkroo commented May 31, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip orchestrates AI agents for zero-human companies
  • Three subsystems are touched: the claude-local adapter (how Claude runs are executed/resumed), request auth middleware (board API keys), and the CLI auth identity endpoint
  • Each had a distinct latent failure: Claude rejects resumes whose transcript carries immutable thinking blocks (surfacing as a hard error), board API-key "touch" can throw a Postgres lock-timeout under contention and fail the request, and /api/cli-auth/me did a redundant DB lookup despite the actor already carrying its identity
  • These hurt run reliability (failed resumes), request reliability (auth failures under load), and add needless DB load on a hot endpoint
  • This pull request adds an immutable-thinking-block detector that triggers a fresh-session retry, makes board-key touch tolerant of lock timeouts (matching agent-key behavior), and reads cli-auth identity straight from req.actor
  • The benefit is fewer spurious run/auth failures and one less query per cli-auth/me call

What Changed

  • claude-local adapter: Added isClaudeImmutableThinkingBlockError (parse.ts) and folded it into the resume-retry path in execute.ts, so a resume that fails due to immutable thinking/redacted_thinking blocks now retries with a fresh session instead of erroring. Also pass PATH explicitly into the ccrotate next command env so account rotation works under restricted execution targets.
  • auth middleware: Wrapped touchBoardApiKey in lock-timeout-tolerant handling (swallows Postgres 55P03 / "lock timeout", logs a warning), mirroring the existing agent-API-key behavior.
  • cli-auth: /api/cli-auth/me now derives user, isInstanceAdmin, companyIds, and memberships from req.actor instead of issuing a second resolveBoardAccess lookup.
  • tests: Added auth-board-key-touch-timeout.test.ts, claude-local resume/immutable-thinking cases, and a cli-auth/me actor-snapshot test.

Verification

  • pnpm --filter @paperclipai/server exec vitest run src/__tests__/cli-auth-routes.test.ts src/__tests__/auth-board-key-touch-timeout.test.ts src/__tests__/claude-local-execute.test.ts — all pass (15 + 18 active tests).
  • Conflict-free resolution confirmed by lint (no errors in the touched files).

Risks

  • Low risk. Changes are additive/defensive: the resume retry only triggers on a newly-detected error class, the lock-timeout handler only swallows the specific 55P03/"lock timeout" case (re-throws everything else), and the cli-auth/me change returns the same shape from already-resolved actor data.

Model Used

  • Claude Opus 4.8 (Anthropic), extended thinking enabled, tool use / code execution via Cursor agent.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots
  • I have considered and documented any risks above
  • I will address all Greptile and reviewer comments before requesting merge

kkroo added 3 commits May 30, 2026 18:54
…sume errors

Claude rejects resume requests whose transcript contains immutable
`thinking`/`redacted_thinking` blocks. Previously only "unknown session"
errors triggered a fresh-session retry, so these failures surfaced as hard
errors. Add isClaudeImmutableThinkingBlockError detection and fold it into
the resume-retry path. Also pass PATH explicitly into the ccrotate command
env so account rotation works under restricted execution targets.
Updating last-used on a board API key could throw a Postgres lock-timeout
(55P03) under contention and fail the request. Wrap touchBoardApiKey in the
same lock-timeout-tolerant handling already used for agent API keys: swallow
55P03 / "lock timeout" errors and log a warning instead of failing auth.
The /api/cli-auth/me handler re-resolved board access via a second DB lookup
even though the authenticated actor already carries the resolved identity.
Read user, isInstanceAdmin, companyIds, and memberships directly from
req.actor instead, dropping the redundant resolveBoardAccess call.
@kkroo
kkroo merged commit e5e4657 into master May 31, 2026
11 of 12 checks passed
@kkroo
kkroo deleted the omar/claude-resume-auth-fixes branch May 31, 2026 01:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant