{"record":{"id":"5f72a67af2e33eb9","repo":"github/github-mcp-server","slug":"github-app-id-or-client-id-is-required-github-app","errorCode":null,"errorMessage":"GitHub App ID or client ID is required (GITHUB_APP_ID)","messagePattern":"GitHub App ID or client ID is required \\(GITHUB_APP_ID\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/githubapp/githubapp.go","lineNumber":53,"sourceCode":"type Config struct {\n\t// AppID is used as the JWT issuer. GitHub accepts an app ID or client ID.\n\tAppID string\n\n\t// InstallationID identifies the installation whose access token is minted.\n\tInstallationID string\n\n\t// PrivateKeyPEM is the RSA key used to sign app JWTs.\n\tPrivateKeyPEM []byte\n\n\t// BaseRESTURL is the REST API base, e.g. https://api.github.com/ for\n\t// github.com or https://HOST/api/v3/ for GitHub Enterprise Server.\n\tBaseRESTURL string\n}\n\nfunc (c Config) validate() error {\n\tswitch {\n\tcase c.AppID == \"\":\n\t\treturn errors.New(\"GitHub App ID or client ID is required (GITHUB_APP_ID)\")\n\tcase c.InstallationID == \"\":\n\t\treturn errors.New(\"GitHub App installation ID is required (GITHUB_APP_INSTALLATION_ID)\")\n\tcase len(c.PrivateKeyPEM) == 0:\n\t\treturn errors.New(\"GitHub App private key is required (GITHUB_APP_PRIVATE_KEY_PATH or GITHUB_APP_PRIVATE_KEY)\")\n\tcase c.BaseRESTURL == \"\":\n\t\treturn errors.New(\"GitHub App REST base URL is required\")\n\t}\n\treturn nil\n}\n\nfunc parsePrivateKey(pemBytes []byte) (*rsa.PrivateKey, error) {\n\tblock, _ := pem.Decode(pemBytes)\n\tif block == nil {\n\t\treturn nil, errors.New(\"no PEM block found in private key\")\n\t}\n\tif key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {\n\t\treturn key, nil\n\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/internal/githubapp/githubapp.go#L35-L71","documentation":"Raised when json.Marshal(minimalRepos) fails while serializing the []MinimalRepository projection built from the ListStarred response. Every field is an int64/string or a pre-formatted time string (UpdatedAt is formatted with a fixed layout), all of which always marshal. The error exists as a defensive invariant; Go's encoder would need a NaN/Inf, chan, func, or cyclic value to fail, which this projection cannot contain.","triggerScenarios":"Only reachable if a fork changes MinimalRepository to hold an unmarshalable type (chan, func, *float64 NaN) or a data race corrupts the slice mid-marshal. Stock types decoded and projected from GitHub's API never trigger it.","commonSituations":"Forked server code adding convenience fields of unsupported types; version skew between a patched go-github and github-mcp-server.","solutions":["Treat as a bug: capture owner/username input and report upstream","Upgrade github-mcp-server to a released version with unmodified DTOs","If maintaining a fork, keep MinimalRepository fields limited to JSON-safe types"],"exampleFix":"// before: fork adds an unsupported field\ntype MinimalRepository struct {\n\t// ...\n\tWatcher chan struct{} `json:\"watcher\"` // marshal fails\n}\n\n// after\ntype MinimalRepository struct {\n\t// ...\n\tWatcherCount int `json:\"watcher_count\"`\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isMarshalError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"failed to marshal\")\n}","tryCatchPattern":"result, _, err := callListStarredRepositories(ctx, username)\nif err != nil && isMarshalError(err) {\n\t// internal serialization bug: report upstream with the input; not retryable\n\tlog.Printf(\"marshal bug on starred listing: username=%s err=%v\", username, err)\n\treturn err\n}","preventionTips":["Run released github-mcp-server versions, not forks with altered DTOs","Keep MinimalRepository-style projections to strings/ints","Report immediately if seen - it signals code corruption, not load"],"tags":["go","json","serialization","defensive"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}