{"record":{"id":"04e9e4409943ab17","repo":"gotify/server","slug":"invalid-client-name","errorCode":null,"errorMessage":"invalid client name","messagePattern":"invalid client name","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"api/oidc.go","lineNumber":134,"sourceCode":"//\t---\n//\tparameters:\n//\t- name: name\n//\t  in: query\n//\t  description: the client name to create after login\n//\t  required: true\n//\t  type: string\n//\tresponses:\n//\t  302:\n//\t    description: Redirect to OIDC provider\n//\t  default:\n//\t    description: Error\n//\t    schema:\n//\t        $ref: \"#/definitions/Error\"\nfunc (a *OIDCAPI) LoginHandler() gin.HandlerFunc {\n\treturn gin.WrapF(func(w http.ResponseWriter, r *http.Request) {\n\t\tclientName := r.URL.Query().Get(\"name\")\n\t\tif clientName == \"\" {\n\t\t\thttp.Error(w, \"invalid client name\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\tstate, err := a.generateState()\n\t\tif err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"failed to generate state: %v\", err), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\ta.pendingSessions.Set(time.Now(), state, &pendingOIDCSession{ClientName: clientName, CreatedAt: time.Now()})\n\t\trp.AuthURLHandler(func() string { return state }, a.Provider, a.promptURLParams()...)(w, r)\n\t})\n}\n\n// swagger:operation GET /auth/oidc/elevate oidc oidcElevate\n//\n// Start the OIDC flow to elevate an existing client session (browser).\n//\n// Redirects the user to the OIDC provider's authorization endpoint. After\n// successful authentication, the referenced client session is elevated for","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/api/oidc.go#L116-L152","documentation":"OIDC LoginHandler requires the 'name' query parameter to identify which configured OIDC client to use. If it is missing or empty, the handler responds with 400 'invalid client name' before generating state.","triggerScenarios":"Navigating to the OIDC login endpoint without ?name=<client>, or with name= empty, e.g. /oidc/login instead of /oidc/login?name=provider-a.","commonSituations":"Frontend links or OIDC client configurations missing the name query param, or users bookmarking the login URL without the parameter.","solutions":["Append the configured client name as a query parameter: /oidc/login?name=<clientName>","Fix the frontend/application code building the login URL to include the name parameter","Verify the client name matches an entry in the server's OIDC client configuration"],"exampleFix":"// before\nwindow.location = '/oidc/login'\n// after\nwindow.location = '/oidc/login?name=my-oidc-provider'","handlingStrategy":"validation","validationCode":"u, _ := url.Parse(\"/oidc/login\")\nq := u.Query()\nq.Set(\"name\", clientName)\nif clientName == \"\" {\n    log.Fatal(\"client name is required\")\n}\nu.RawQuery = q.Encode()\nhttp.Redirect(w, r, u.String(), http.StatusFound)","typeGuard":null,"tryCatchPattern":"resp, err := http.Get(loginURL)\nif resp.StatusCode == 400 {\n    body, _ := io.ReadAll(resp.Body)\n    if strings.Contains(string(body), \"invalid client name\") {\n        log.Printf(\"append ?name=<client> to %s\", loginURL)\n    }\n}","preventionTips":["Always build the login URL with the name query parameter","Store client names in one config constant reused by frontend and backend","Validate links pointing at /oidc/login in e2e tests"],"tags":["oidc","http","bad-request"],"backgroundTag":"missing-query-parameter","analyzedSha":"14bfc256276775c425f988d621dccfe705de18ac","analyzedAt":"2026-09-05T12:52:36.781Z","contentChangedAt":"2026-09-05T12:52:36.781Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}