JuliusBrussee/caveman · error
githubapp: repo installation response carried no id
Error message
githubapp: repo installation response carried no id
What it means
Post-decode check in GetRepoInstallation(): the decoded response has no positive ID, so GitHub returned an unusable installation object. The result is rejected to keep authorization decisions grounded in a verified installation id.
Source
Thrown at shared/platform/githubapp/githubapp.go:291
func (a *App) GetRepoInstallation(ctx context.Context, owner, name string) (Installation, error) {
var out Installation
jwt, err := a.AppJWT()
if err != nil {
return out, err
}
status, raw, err := a.do(ctx, "Bearer "+jwt, http.MethodGet,
"/repos/"+url.PathEscape(owner)+"/"+url.PathEscape(name)+"/installation", nil)
if err != nil {
return out, err
}
if status != http.StatusOK {
return out, fmt.Errorf("githubapp: get repo installation %s/%s: HTTP %d: %s", owner, name, status, snippet(raw))
}
if err := json.Unmarshal(raw, &out); err != nil {
return out, fmt.Errorf("githubapp: decode repo installation: %w", err)
}
if out.ID <= 0 {
return Installation{}, fmt.Errorf("githubapp: repo installation response carried no id")
}
return out, nil
}
// GetFileContent reads one repository file with an installation token. The
// content endpoint returns base64; callers receive decoded bytes with a strict
// 64 KiB post-decode ceiling because connection proofs are tiny text files.
func (a *App) GetFileContent(ctx context.Context, token, owner, name, path, ref string) ([]byte, error) {
segments := strings.Split(strings.Trim(path, "/"), "/")
if len(segments) == 0 || segments[0] == "" {
return nil, fmt.Errorf("githubapp: content path is required")
}
for i := range segments {
segments[i] = url.PathEscape(segments[i])
}
endpoint := "/repos/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/contents/" + strings.Join(segments, "/")
if strings.TrimSpace(ref) != "" {
endpoint += "?" + url.Values{"ref": {ref}}.Encode()View on GitHub (pinned to 766dce6b13)
Solutions
- Retry the lookup; inspect the raw response if it recurs
- Treat as failure of the authorization proof and do not activate the binding
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at shared/platform/githubapp/githubapp.go:291 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/3c29636a105248f0.
Report an issue: GitHub.