multica-ai/multica · error

local server error

Error message

local server error: %w

What it means

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.

Solutions

  1. Close old login tabs/windows and rerun `multica login` to get a fresh state
  2. Complete the flow promptly in the single browser window the CLI opened
  3. Disable URL-rewriting extensions for the login domain or use a clean browser profile
  4. Fall back to `multica login --token <PAT>` if the browser flow keeps failing
Defensive patterns

Strategy: retry

Try / catch

# stale state is fixed by a fresh run
for i in 1 2; do multica login && break; done

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/5acf4b2d0e03992f. Report an issue: GitHub.

Appendix: source

Thrown at server/cmd/multica/cmd_auth.go:308

		if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
			errCh <- err
		}
	}()
	defer srv.Close()

	// Open the browser.
	fmt.Fprintln(os.Stderr, "Opening browser to authenticate...")
	if err := openBrowser(loginURL); err != nil {
		fmt.Fprintf(os.Stderr, "Could not open browser automatically.\n")
	}
	fmt.Fprint(os.Stderr, browserLoginInstructions(loginURL, callbackHost, port, runningInSSHSession()))

	// Wait for the JWT from the callback (timeout 5 minutes).
	var jwtToken string
	select {
	case jwtToken = <-jwtCh:
	case err := <-errCh:
		return fmt.Errorf("local server error: %w", err)
	case <-time.After(5 * time.Minute):
		return fmt.Errorf("timed out waiting for authentication")
	}

	// Use the JWT to create a PAT via the existing API.
	client := cli.NewAPIClient(serverURL, "", jwtToken)

	ctx, cancel := cli.APIContext(context.Background())
	defer cancel()

	hostname, _ := os.Hostname()
	if hostname == "" {
		hostname = "unknown"
	}
	patName := fmt.Sprintf("CLI (%s)", hostname)
	expiresInDays := 90

	var patResp struct {

View on GitHub (pinned to 2c0912b6ec)