mislav/hub · error
%s\n%s
Error message
%s\n%s
What it means
This is the tail of the HTTP error formatter (FormatError). After assembling the base error string (and any errorMessage from the response), it appends, on separate lines (%s\n%s), either a GitHub SSO authorization challenge or an insufficient-OAuth-scopes warning when those validators detect them. The two-line message means the request failed AND the response carried an SSO or scope signal.
Source
Thrown at github/client.go:1259
errorSentences = append(errorSentences, fmt.Sprintf("Not allowed to change field \"%s\"", err.Field))
}
}
var errorMessage string
if len(errorSentences) > 0 {
errorMessage = strings.Join(errorSentences, "\n")
} else {
errorMessage = e.Message
if action == "getting current user" && e.Message == "Resource not accessible by integration" {
errorMessage = errorMessage + "\nYou must specify GITHUB_USER via environment variable."
}
}
if errorMessage != "" {
errStr = fmt.Sprintf("%s\n%s", errStr, errorMessage)
}
if ssoErr := ValidateGitHubSSO(e.Response); ssoErr != nil {
return fmt.Errorf("%s\n%s", errStr, ssoErr)
}
if scopeErr := ValidateSufficientOAuthScopes(e.Response); scopeErr != nil {
return fmt.Errorf("%s\n%s", errStr, scopeErr)
}
return errors.New(errStr)
}
// ValidateGitHubSSO checks for the challenge via `X-Github-Sso` header
func ValidateGitHubSSO(res *http.Response) error {
if res.StatusCode != 403 {
return nil
}
sso := res.Header.Get("X-Github-Sso")
if !strings.HasPrefix(sso, "required; url=") {
return nilView on GitHub (pinned to 5c547ed804)
Solutions
- Follow the SSO authorization URL printed in the message (or in the X-Github-Sso header) to authorize your token for the organization.
- Regenerate the token with the required scopes (repo, read:org, workflow as needed) if a scope warning is appended.
- For fine-grained tokens, grant the token access to the specific organization/repository.
- Update the stored token (e.g. `gh auth login` or re-run the library's auth flow) after changing scopes.
Defensive patterns
Strategy: try-catch
Validate before calling
req, _ := http.NewRequest("GET", "https://api.github.com/user", nil)
req.Header.Set("Authorization", "Bearer "+token)
res, _ := http.DefaultClient.Do(req)
if sso := res.Header.Get("X-Github-Sso"); strings.HasPrefix(sso, "required; url=") {
return fmt.Errorf("authorize token at %s", sso[strings.IndexByte(sso,'=')+1:])
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "authorize your token") || strings.Contains(err.Error(), "OAuth") {
return fmt.Errorf("token needs SSO authorization or more scopes: %w", err)
}
} Prevention
- Authorize the PAT for every SSO org you access (token → Configure SSO).
- Create tokens with the full set of needed scopes: repo, read:org, workflow.
- Re-authorize tokens after orgs enable or change SAML SSO.
- Prefer GitHub Apps/fine-grained tokens for automation to avoid SSO per-token authorization.
When it happens
Trigger: Any REST call whose response triggers ValidateGitHubSSO (X-Github-Sso header present) or ValidateSufficientOAuthScopes (404/403 with scope mismatch), with errStr already containing the base HTTP error from the response errors.
Common situations: Accessing an org resource with a token not SSO-authorized for that org (common after enabling SAML SSO); using a classic PAT whose scopes (repo, read:org) don't cover the requested resource; enterprise deployments requiring fine-grained permissions.
Related errors
- Error creating fork: %s already exists on %s
- Error: that fork is not available anymore
- %s\nAre you sure that %s exists?
- Unable to find release with tag name `%s'
- API error: %s
AI-assisted analysis of mislav/hub@5c547ed804 (2026-09-01).
Data as JSON: /api/errors/e7db68db8eb4291e.
Report an issue: GitHub.