Skip to content

Unlock by path fails with 404/409 when the snapshot names a released-and-reissued lock id: the spec's one refresh + one retry isn't implemented #71

Description

@matt-edmondson

Plan

docs/superpowers/specs/2026-08-19-locks-subsystem-design.md#L126

Unlock by path resolves ids from the current snapshot. A resolution that upstream then answers 404 or 409 triggers one snapshot refresh and one retry for that item only, because a stale snapshot can name a lock id that has since been released and reissued.

The spec's As built section doesn't record a departure from this.

What exists today

LockFanOut.RunOneAsync (GitLfsCache/Locks/LockFanOut.cs:130-160) resolves a path to an id from the snapshot. It refreshes only when the path is missing from the snapshot. SendWithRetriesAsync retries only on throttling (429, or 403 with Retry-After), so a 404 or 409 for a stale id goes back to the client as ok:false immediately.

What's missing

Suppose the path's lock was released and re-taken under a new id after the snapshot was built. The unlock is sent to the old id, upstream answers 404 or 409, and the user's unlock fails even though the lock exists. The spec asks for:

  • one snapshot refresh on that answer,
  • re-resolving the path,
  • one retry.

This applies only to items the proxy resolved from a path. Ids the client supplied are never retried.

Acceptance criteria

  • A path-resolved unlock whose first attempt returns 404 or 409 refreshes once, re-resolves, and retries once. If the retry also fails, the item reports upstream's status.
  • An unlock by a client-supplied id is never retried on 404/409.
  • The retry refresh goes through the same single-flight and limiter as the other resolution refreshes.
  • Tests cover both the retry path and the no-retry path for client-supplied ids.

Dependencies

Coordinate with #63. It restructures unlock-by-path resolution into one refresh per request, and this retry should use that same mechanism.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions