JuliusBrussee/caveman · error

githubapp: mint token: HTTP %d: %s

Error message

githubapp: mint token: HTTP %d: %s

What it means

Fires in MintInstallationToken() when GitHub returns a non-201 from POST /app/installations/{id}/access_tokens — the App JWT was rejected, the installation was uninstalled, or the repo is not accessible to the installation. Includes status and body snippet.

Source

Thrown at shared/platform/githubapp/githubapp.go:217

	scopedPermissions := make(map[string]string, len(perms))
	for name, level := range perms {
		if !allowedPermissions[name] || (level != "read" && level != "write") {
			return InstallationToken{}, fmt.Errorf("githubapp: permission %q=%q exceeds the least-agency allowlist", name, level)
		}
		scopedPermissions[name] = level
	}
	jwt, err := a.AppJWT()
	if err != nil {
		return InstallationToken{}, err
	}
	body := map[string]any{"permissions": scopedPermissions, "repositories": []string{repository}}
	status, raw, err := a.do(ctx, "Bearer "+jwt, http.MethodPost,
		"/app/installations/"+strconv.FormatInt(installationID, 10)+"/access_tokens", body)
	if err != nil {
		return InstallationToken{}, err
	}
	if status != http.StatusCreated {
		return InstallationToken{}, fmt.Errorf("githubapp: mint token: HTTP %d: %s", status, snippet(raw))
	}
	var out InstallationToken
	if err := json.Unmarshal(raw, &out); err != nil {
		return InstallationToken{}, fmt.Errorf("githubapp: decode token response: %w", err)
	}
	if out.Token == "" {
		return InstallationToken{}, fmt.Errorf("githubapp: token response carried no token")
	}
	return out, nil
}

// RevokeToken DELETEs /installation/token authenticated with the token itself —
// the job-end "drop all agency" step. A best-effort revoke; the ~1h natural
// expiry is the backstop.
func (a *App) RevokeToken(ctx context.Context, token string) error {
	status, raw, err := a.do(ctx, "Bearer "+token, http.MethodDelete, "/installation/token", nil)
	if err != nil {
		return err

View on GitHub (pinned to 766dce6b13)

Solutions

  1. Verify the installation still exists and includes the requested repository (404/422)
  2. Refresh the App JWT and retry on transient 5xx; check App permission settings on GitHub
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at shared/platform/githubapp/githubapp.go:217 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/ccb88a37132d31a1. Report an issue: GitHub.