Skip to content

Error Codes

GPC uses structured error handling with deterministic exit codes and machine-readable error objects. Every error includes a code, message, and suggestion for how to fix it.

Exit Codes

CodeNameMeaningCI Action
0SuccessCommand completed successfullyContinue pipeline
1General ErrorUnclassified errorFail the job, investigate
2Usage ErrorInvalid arguments or flagsFix the command invocation
3Auth ErrorAuthentication failedCheck GPC_SERVICE_ACCOUNT secret
4API ErrorGoogle Play API returned an errorCheck permissions, retry if rate limited
5Network ErrorNetwork connectivity issueRetry the step
6Threshold BreachVitals metric exceeded thresholdHalt rollout, alert team
10Plugin ErrorPlugin failed to load or executeCheck plugin configuration

Using Exit Codes in CI Scripts

bash
#!/bin/bash
# exit-code-handler.sh
gpc releases upload app.aab --track internal --json
EXIT_CODE=$?

case $EXIT_CODE in
  0)
    echo "Upload successful"
    ;;
  2)
    echo "Invalid arguments. Check command syntax."
    exit 2
    ;;
  3)
    echo "Auth failed. Is GPC_SERVICE_ACCOUNT set correctly?"
    exit 3
    ;;
  4)
    echo "API error. Check Play Console permissions."
    exit 4
    ;;
  5)
    echo "Network error. Retrying..."
    gpc releases upload app.aab --track internal --json
    ;;
  6)
    echo "Vitals threshold breached. Halting rollout."
    gpc releases rollout halt --track production --json
    exit 6
    ;;
  10)
    echo "Plugin error. Check plugin installation."
    exit 10
    ;;
  *)
    echo "Unexpected error: $EXIT_CODE"
    exit 1
    ;;
esac

GitHub Actions Step Conditional

yaml
- name: Upload release
  id: upload
  run: gpc releases upload app.aab --track internal --json
  continue-on-error: true

- name: Handle auth failure
  if: steps.upload.outcome == 'failure'
  run: |
    echo "::error::Upload failed. Check GPC_SERVICE_ACCOUNT and Play Console permissions."
    exit 1

JSON Error Format

When a command fails, JSON output follows this structure:

json
{
  "success": false,
  "error": {
    "code": "AUTH_TOKEN_EXPIRED",
    "message": "Access token has expired",
    "suggestion": "Run 'gpc auth login' to re-authenticate"
  }
}
FieldTypeDescription
successbooleanAlways false for errors
error.codestringMachine-readable error identifier
error.messagestringHuman-readable description
error.suggestionstringActionable fix (when available)

Parse errors in CI scripts:

bash
RESULT=$(gpc releases status --json 2>&1) || true
ERROR_CODE=$(echo "$RESULT" | jq -r '.error.code // empty')

if [[ -n "$ERROR_CODE" ]]; then
  SUGGESTION=$(echo "$RESULT" | jq -r '.error.suggestion // "No suggestion available"')
  echo "Error: $ERROR_CODE$SUGGESTION"
fi

Error Code Prefixes

Error codes are namespaced by prefix to indicate the subsystem that generated the error.

AUTH_* -- Authentication Errors

Exit code: 3

CodeMessageCauseFix
AUTH_TOKEN_EXPIREDAccess token has expiredToken TTL exceededRun gpc auth login or check service account
AUTH_INVALID_CREDENTIALSInvalid credentialsMalformed service account JSONVerify JSON file is valid and complete
AUTH_MISSING_CREDENTIALSNo credentials foundNo auth method configuredSet GPC_SERVICE_ACCOUNT or run gpc auth login
AUTH_INSUFFICIENT_SCOPEInsufficient scopesToken missing required scopeRe-authenticate with correct scopes
AUTH_REFRESH_FAILEDToken refresh failedRefresh token revoked or expiredRun gpc auth login again
AUTH_KEYFILE_NOT_FOUNDKey file not foundFile path in config does not existCheck GPC_SERVICE_ACCOUNT path
AUTH_KEYFILE_INVALIDInvalid key file formatFile is not valid service account JSONDownload a fresh key from Google Cloud Console

API_* -- Google Play API Errors

Exit code: 4

CodeHTTP StatusCauseFix
API_RATE_LIMITED429Too many requestsWait and retry; reduce GPC_RATE_LIMIT
API_NOT_FOUND404Resource not foundVerify the package name or resource exists
API_PERMISSION_DENIED403Service account lacks required permissionGrant permission in Play Console > Users
API_UNAUTHORIZED401Invalid or expired tokenRe-authenticate
API_VALIDATION_FAILED400Edit validation failed before commitCheck error details for specific field issues
API_EDIT_CONFLICT409Another edit in progress or Console usedRetry the operation (GPC creates fresh edits)
API_QUOTA_EXCEEDED429Daily or per-minute quota hitWait for quota reset or request increase
API_INVALID_ARGUMENT400API rejected a field valueCheck the error message for the specific field
API_PRECONDITION_FAILED412Required state not metCheck release status, version codes, etc.
API_SERVER_ERROR5xxGoogle server errorAuto-retried with exponential backoff
API_TIMEOUT--Request exceeded timeoutIncrease GPC_TIMEOUT

CONFIG_* -- Configuration Errors

Exit code: 2

CodeMessageCauseFix
CONFIG_NOT_FOUNDConfig file not foundNo .gpcrc.json in project or user dirRun gpc config init
CONFIG_VALIDATION_ERRORInvalid configConfig file has invalid fieldsRun gpc config show to inspect
CONFIG_MISSING_APPNo app specified--app flag and GPC_APP both missingSet GPC_APP or pass --app
CONFIG_MISSING_DEVELOPER_IDNo developer IDRequired for user/grant commandsSet GPC_DEVELOPER_ID or pass --developer-id

UPLOAD_* -- Upload Errors

Exit code: 1

CodeMessageCauseFix
UPLOAD_FILE_NOT_FOUNDFile not foundUpload file path does not existCheck the file path
UPLOAD_INVALID_FORMATInvalid file formatFile is not a valid AAB or APKVerify the file was built correctly
UPLOAD_FILE_TOO_LARGEFile exceeds size limitAAB/APK over 150MBReduce bundle size or use dynamic delivery
UPLOAD_DUPLICATE_VERSIONDuplicate version codeVersion code already usedIncrement versionCode in build.gradle
UPLOAD_MAPPING_INVALIDInvalid mapping fileProGuard/R8 mapping file is malformedCheck the mapping file format

PLUGIN_* -- Plugin Errors

Exit code: 10

CodeMessageCauseFix
PLUGIN_NOT_FOUNDPlugin not foundPlugin package not installedInstall the plugin: npm install <plugin>
PLUGIN_INVALID_PERMISSIONInvalid permissionPlugin requests unknown permissionUpdate the plugin or report to the author
PLUGIN_PERMISSION_DENIEDPermission deniedPlugin not approved by userRun gpc plugins approve <name>
PLUGIN_LOAD_FAILEDFailed to load pluginPlugin has syntax or runtime errorsCheck plugin code or update to latest version
PLUGIN_HOOK_FAILEDHook execution failedPlugin hook threw an errorCheck plugin logs; error is non-fatal

NETWORK_* -- Network Errors

Exit code: 5

CodeMessageCauseFix
NETWORK_TIMEOUTRequest timed outServer did not respond in timeIncrease GPC_TIMEOUT or retry
NETWORK_CONNECTION_REFUSEDConnection refusedCannot reach API endpointCheck network connectivity and proxy settings
NETWORK_DNS_FAILUREDNS resolution failedCannot resolve API hostnameCheck DNS configuration
NETWORK_PROXY_ERRORProxy errorHTTPS proxy rejected the requestCheck HTTPS_PROXY configuration
NETWORK_TLS_ERRORTLS errorCertificate validation failedCheck GPC_CA_CERT or system certificates

THRESHOLD_* -- Vitals Threshold Errors

Exit code: 6

CodeMessageCauseFix
THRESHOLD_CRASH_RATECrash rate threshold breachedCrash rate exceeds --threshold valueInvestigate crashes, halt rollout
THRESHOLD_ANR_RATEANR rate threshold breachedANR rate exceeds --threshold valueInvestigate ANRs, halt rollout

Error Class Hierarchy

GPC uses a typed error hierarchy. All errors extend the base GpcError class.

GpcError (base)
├── AuthError
│   ├── TokenExpiredError
│   ├── InvalidCredentialsError
│   └── MissingCredentialsError
├── ApiError
│   ├── RateLimitError
│   ├── NotFoundError
│   ├── PermissionDeniedError
│   └── ValidationError
├── ConfigError
│   ├── ConfigNotFoundError
│   └── ConfigValidationError
└── PluginError

Every error instance includes:

typescript
interface GpcError {
  code: string; // e.g., "AUTH_TOKEN_EXPIRED"
  message: string; // Human-readable description
  suggestion: string; // Actionable fix
  exitCode: number; // Process exit code (1-6, 10)
}

Common Error Scenarios

"Permission denied" on upload

Error: API_PERMISSION_DENIED
Message: The caller does not have permission
Suggestion: Grant 'Release apps to testing tracks' to the service account in Play Console

Fix: Go to Play Console > Users and permissions > invite the service account email > grant "Release apps to testing tracks" (or "Release to production" for production track).

"No credentials found" in CI

Error: AUTH_MISSING_CREDENTIALS
Message: No authentication credentials found
Suggestion: Set GPC_SERVICE_ACCOUNT environment variable or run 'gpc auth login'

Fix: Ensure the GPC_SERVICE_ACCOUNT secret is set in your CI provider and passed as an environment variable to the job.

"Edit conflict" during release

Error: API_EDIT_CONFLICT
Message: Edit was invalidated by a concurrent change
Suggestion: Retry the operation. Avoid making changes in Play Console during CI releases.

Fix: Retry the command. If it persists, ensure no one is making changes in the Play Console web UI while the CI pipeline is running.

"Threshold breach" halting rollout

Error: THRESHOLD_CRASH_RATE
Message: Crash rate 2.4% exceeds threshold 2.0%
Suggestion: Investigate crash clusters with 'gpc vitals crashes' and consider halting the rollout

Fix: Run gpc vitals crashes --json to identify crash clusters. Consider halting the rollout with gpc releases rollout halt --track production.

Released under the MIT License.