{"record":{"id":"5acf4b2d0e03992f","repo":"multica-ai/multica","slug":"local-server-error-w","errorCode":null,"errorMessage":"local server error: %w","messagePattern":"local server error: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_auth.go","lineNumber":308,"sourceCode":"\t\tif err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {\n\t\t\terrCh <- err\n\t\t}\n\t}()\n\tdefer srv.Close()\n\n\t// Open the browser.\n\tfmt.Fprintln(os.Stderr, \"Opening browser to authenticate...\")\n\tif err := openBrowser(loginURL); err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Could not open browser automatically.\\n\")\n\t}\n\tfmt.Fprint(os.Stderr, browserLoginInstructions(loginURL, callbackHost, port, runningInSSHSession()))\n\n\t// Wait for the JWT from the callback (timeout 5 minutes).\n\tvar jwtToken string\n\tselect {\n\tcase jwtToken = <-jwtCh:\n\tcase err := <-errCh:\n\t\treturn fmt.Errorf(\"local server error: %w\", err)\n\tcase <-time.After(5 * time.Minute):\n\t\treturn fmt.Errorf(\"timed out waiting for authentication\")\n\t}\n\n\t// Use the JWT to create a PAT via the existing API.\n\tclient := cli.NewAPIClient(serverURL, \"\", jwtToken)\n\n\tctx, cancel := cli.APIContext(context.Background())\n\tdefer cancel()\n\n\thostname, _ := os.Hostname()\n\tif hostname == \"\" {\n\t\thostname = \"unknown\"\n\t}\n\tpatName := fmt.Sprintf(\"CLI (%s)\", hostname)\n\texpiresInDays := 90\n\n\tvar patResp struct {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_auth.go#L290-L326","documentation":"During the wait for the browser callback, the local server's /callback handler can push an error (e.g. missing or mismatched state parameter, malformed request) onto errCh. Receiving from errCh aborts login with this wrapped error.","triggerScenarios":"A callback request whose cli_state does not match the issued state (CSRF check failure); something else hitting /callback with unexpected query parameters; browser extension or security product rewriting the redirect URL.","commonSituations":"Stale/multiple login tabs completing an old flow against a new listener; privacy extensions stripping query params from redirects; local proxies altering the callback URL.","solutions":["Close old login tabs/windows and rerun `multica login` to get a fresh state","Complete the flow promptly in the single browser window the CLI opened","Disable URL-rewriting extensions for the login domain or use a clean browser profile","Fall back to `multica login --token <PAT>` if the browser flow keeps failing"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"# stale state is fixed by a fresh run\nfor i in 1 2; do multica login && break; done","preventionTips":["Close stale login tabs before starting a new login","Complete the flow in the window the CLI opened; avoid parallel logins"],"tags":["cli","auth","login","csrf","browser"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}