Skip to content

A 2xx batch response that isn't valid JSON, or has a mistyped field, returns 500 instead of 502 (e.g. an SSO page served with 200) #81

Description

@matt-edmondson

What's wrong

ObjectRouteHandler.BatchAsync (GitLfsCache/Endpoints/ObjectRouteHandler.cs ~lines 80–100) relays non-2xx responses verbatim. For any 2xx, it calls JsonNode.ParseAsync on the body with no try/catch. Only a null result is mapped to 502. Nothing above it catches JsonException: the route is served through MapFallback, and no exception handler is registered.

The body that does parse is then read in GitLfsCache/Batch/BatchRewriter.cs with direct GetValue<string>() / GetValue<long>() calls on oid, size, the action href, and header values. A value of the wrong JSON type makes these throw InvalidOperationException. For example, "size": "123" or a numeric header value.

The locks subsystem's As-built section says "all untrusted JSON is read through a JsonValues helper". The batch path was never moved over.

Failure scenarios

  • The upstream, or a gateway in front of it, answers POST …/info/lfs/objects/batch with 200 text/html (a forge sign-in or SSO interstitial, or a captive proxy). JsonNode.ParseAsync throws, and git-lfs gets a bare 500 from the cache.
  • The upstream returns valid JSON with "size": "123". BatchRewriter throws, and the result is again 500.

A null body already gets 502. These cases are the same kind of problem (the upstream sent something we can't use), but they surface as the proxy's own internal error. That points operators at the wrong component and hides upstream's actual response.

Suggested fix

  • Catch JsonException around the parse and answer 502 with a short reason, the same as the existing null-body branch. Relaying the upstream response verbatim when it isn't application/json is also reasonable.
  • Read the batch fields in BatchRewriter through the existing JsonValues helper, and treat a malformed object as a 502 or skip the entry, rather than throwing.

Acceptance criteria

  • Tests with a stub upstream show that a 200 text/html batch body and a 200 JSON body with "size": "123" each produce 502 (or a verbatim relay), never 500.

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions