{"record":{"id":"8f6a67f3fa4d3a11","repo":"tailscale/tailscale","slug":"w-w","errorCode":null,"errorMessage":"%w: %w","messagePattern":"%w: %w","errorType":"http","errorClass":"HTTPError","httpStatus":499,"severity":"error","filePath":"tsweb/tsweb.go","lineNumber":806,"sourceCode":"\t\tif hs, ok := errors.AsType[HTTPStatuser](err); ok {\n\t\t\thErr = hs.HTTPStatus()\n\t\t\thAsOK = true\n\t\t}\n\t}\n\tif hAsOK {\n\t\thOK = true\n\t\tif hErr.Code == 0 {\n\t\t\tlw.logf(\"[unexpected] HTTPError %v did not contain an HTTP status code, sending internal server error\", hErr)\n\t\t\thErr.Code = http.StatusInternalServerError\n\t\t}\n\t} else if v, ok := vizerror.As(err); ok {\n\t\thErr = Error(http.StatusInternalServerError, v.Error(), nil)\n\t} else if reqCancelled(r, err) {\n\t\t// 499 is the Nginx convention meaning \"Client Closed Connection\".\n\t\tif errors.Is(err, context.Canceled) || errors.Is(err, http.ErrAbortHandler) {\n\t\t\thErr = Error(499, \"\", err)\n\t\t} else {\n\t\t\thErr = Error(499, \"\", fmt.Errorf(\"%w: %w\", context.Canceled, err))\n\t\t}\n\t} else {\n\t\t// Omit the friendly message so HTTP logs show the bare error that was\n\t\t// returned and we know it's not a HTTPError.\n\t\thErr = Error(http.StatusInternalServerError, \"\", err)\n\t}\n\n\t// Tell the logger what error we wrote back to the client.\n\tif pb := errCallback.Value(r.Context()); pb != nil {\n\t\tpb(hErr)\n\t\tlogged = true\n\t}\n\n\tif r.Context().Err() != nil {\n\t\treturn logged\n\t}\n\n\tif lw.code != 0 {","sourceCodeStart":788,"sourceCodeEnd":824,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/tsweb/tsweb.go#L788-L824","documentation":"The generic '%w: %w' wrapper used by handleError in tsweb to join the user-visible HTTPError with the underlying cause while rendering an error response. It preserves both the structured HTTP status error and the root error for the response body and logging.","triggerScenarios":"Thrown at tsweb/tsweb.go:806 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Unwrap with errors.Is/As to recover both the HTTPError (status code) and the root cause","Ensure handlers wrap failures in tsweb.Error with a meaningful inner error so this join is informative","Log the joined error for server-side diagnosis while sending the HTTPError message to the client"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}