JuliusBrussee/caveman · error
githubapp: installation response identity mismatch
Error message
githubapp: installation response identity mismatch
What it means
Security check in GetInstallation(): GitHub's response does not match the requested identity — the returned installation id differs from the requested one, or the account id/login is missing. This fails closed against spoofed or inconsistent responses during callback validation.
Source
Thrown at shared/platform/githubapp/githubapp.go:178
return out, fmt.Errorf("githubapp: installation id must be positive")
}
jwt, err := a.AppJWT()
if err != nil {
return out, err
}
status, raw, err := a.do(ctx, "Bearer "+jwt, http.MethodGet,
"/app/installations/"+strconv.FormatInt(installationID, 10), nil)
if err != nil {
return out, err
}
if status != http.StatusOK {
return out, fmt.Errorf("githubapp: get installation: HTTP %d: %s", status, snippet(raw))
}
if err := json.Unmarshal(raw, &out); err != nil {
return out, fmt.Errorf("githubapp: decode installation: %w", err)
}
if out.ID != installationID || out.Account.ID <= 0 || strings.TrimSpace(out.Account.Login) == "" {
return Installation{}, fmt.Errorf("githubapp: installation response identity mismatch")
}
return out, nil
}
// MintInstallationToken POSTs /app/installations/{id}/access_tokens narrowed to
// `repos` and `perms`, returning a ~1h token. Defaults (perms nil) are
// contents:write + pull_requests:write — enough to push a branch and open a draft
// PR, never to merge.
func (a *App) MintInstallationToken(ctx context.Context, installationID int64, repos []string, perms map[string]string) (InstallationToken, error) {
if installationID <= 0 {
return InstallationToken{}, fmt.Errorf("githubapp: installation id must be positive")
}
if len(repos) != 1 || strings.TrimSpace(repos[0]) == "" {
return InstallationToken{}, fmt.Errorf("githubapp: exactly one repository is required")
}
repository := strings.TrimSpace(repos[0])
if perms == nil {
perms = map[string]string{"contents": "write", "pull_requests": "write"}View on GitHub (pinned to 766dce6b13)
Solutions
- Treat as an authorization failure: do not trust the supplied installation id; re-run the connect flow
- Investigate if this recurs, as it indicates API responses not matching requests (proxy/tampering or id confusion)
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at shared/platform/githubapp/githubapp.go:178 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/453b0567d4141f0d.
Report an issue: GitHub.