A page where JSON was expected names the portal, not the doctype - #117
Merged
Conversation
Reported as `Unexpected token '<', "<!DOCTYPE "... is not valid JSON` on the
GitLab review-credential check. The chain is exact: an access portal in front
of a corporate instance answers `GET {instance}/api/v4/user` with its own
sign-in page at 200, so `res.ok` is true, `res.json()` throws a SyntaxError,
and `connectVcs` — which passes `err.message` through for any Error — hands
that string to the wizard verbatim. A JSON parser describing the first
character of a web page, presented as the diagnosis.
Both adapters now read the body as text and parse it themselves, so a 2xx that
is not JSON becomes a VcsError naming the likely cause: a portal that serves
its login page at 200, which specd cannot work around because it speaks the API
with a token and cannot complete a browser sign-in. Non-HTML bodies are quoted
rather than guessed at. 204 keeps its early return — an empty body is not a
broken one, and `propose` deletes a branch on every run.
The web client had the same hole on its success path: it handles a non-JSON
*error* body carefully and then does an unguarded `JSON.parse` on a 2xx. That
one fires when something answers in the API's place — a dev server on the same
port, a proxy — and it now says so, and names the base URL it was talking to.
This is the same class as the transport guard in 0020's follow-up: a failure
that is not an HttpException reaching a person as either an opaque 500 or a
parser error. Two more instances of it, closed the same way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported from the wizard's GitLab review-credential check:
The chain, exactly
/projects/:slug/connections/vcswithreviewProvider: 'gitlab'.GitLabAdapter.verify()→GET {instance}/api/v4/user.page, at 200. The request never reached GitLab.
res.okis true, so the error branch is skipped andres.json()throws aSyntaxError.connectVcspasseserr.messagethrough for anyError, so that stringbecomes the 400 body.
A JSON parser describing the first character of a web page, presented as the
diagnosis.
The fix
Both adapters now read the body as text and parse it themselves. A 2xx that
is not JSON becomes a
VcsErrornaming the likely cause:upstream connect erroris a proxy, not a portal).proposedeletes a branch on every run — pinned by a test that drives thewhole
proposesequence rather than the private method.these portals.
The web client had the same hole on the other side: it handles a non-JSON
error body carefully and then does an unguarded
JSON.parseon the successpath. That one fires when something answers in the API's place — a dev server
on the same port, a proxy — and it now says so and names the base URL it was
talking to.
This is the same class as the transport guard added alongside decision 0020: a
failure that is not an
HttpExceptionreaching a person as an opaque 500 or aparser error. Two more instances, closed the same way.
What this does not fix
Nothing here makes the connection work. If a portal intercepts
/api/v4, notoken specd holds will help — it speaks the API directly and cannot complete a
browser sign-in. The resolutions are environmental, and both
docs/gitlab.mdand the published GitLab page now say so:
VPN itself rather than the public hostname);
PRIVATE-TOKEN;Making the error honest is the whole of this change. It turns an unanswerable
symptom into a question someone's platform team can act on.
Verify
pnpm typecheck && pnpm test, pluspnpm buildandpnpm site:check— 1,764links, none broken. 4 new adapter tests covering the portal page, a non-HTML
body, the
VcsErrortype (so the controller answers 400 and not 500), and the204 path.