bytedance/deer-flow · error · GitHubAppAuthError

GITHUB_APP_ID is not set

Error message

GITHUB_APP_ID is not set

What it means

GitHubAppAuthError raised by app_id() when the GITHUB_APP_ID environment variable is unset or empty. The value is read fresh on every call so operators can rotate it without restart; any caller minting an App JWT (installation token flow) needs it.

Source

Thrown at backend/app/gateway/github/app_auth.py:89

async def _lock_for(installation_id: int) -> asyncio.Lock:
    """Return the lock dedicated to ``installation_id``, creating on demand."""
    async with _install_locks_lock:
        lock = _install_locks.get(installation_id)
        if lock is None:
            lock = asyncio.Lock()
            _install_locks[installation_id] = lock
        return lock


def app_id() -> int:
    """Return the configured GitHub App id, or raise if unset.

    Read fresh on every call so operators can rotate it without a process
    restart.
    """
    raw = os.environ.get(_APP_ID_ENV)
    if not raw:
        raise GitHubAppAuthError(f"{_APP_ID_ENV} is not set")
    try:
        return int(raw.strip())
    except ValueError as exc:
        raise GitHubAppAuthError(f"{_APP_ID_ENV}={raw!r} is not an integer") from exc


def load_app_private_key() -> str:
    """Return the App's RSA private key as a PEM string.

    Reads from ``GITHUB_APP_PRIVATE_KEY`` (inline PEM) if set, else from
    the path in ``GITHUB_APP_PRIVATE_KEY_PATH``. Inline takes precedence
    so operators can roll a key by setting an env var instead of moving
    files around in production.
    """
    inline = os.environ.get(_PRIVATE_KEY_ENV)
    if inline and inline.strip():
        return inline

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Set GITHUB_APP_ID (numeric App id from the GitHub App settings page) in the Gateway process environment: export it in docker/compose env, .env consumed by the orchestrator, or the service unit
  2. Redeploy/restart so the process picks up the env (reads are fresh per call, so a restart is only needed for the env change)
  3. Confirm the sibling vars GITHUB_APP_PRIVATE_KEY (or _PATH) are set too — the next failure is the key
  4. Verify with `docker exec <gateway> printenv GITHUB_APP_ID` or equivalent inside the running process context

Example fix

# before
docker compose up -d   # GITHUB_APP_ID unset -> GitHubAppAuthError: GITHUB_APP_ID is not set
# after (docker-compose.override.yml)
services:
  gateway:
    environment:
      GITHUB_APP_ID: "123456"
      GITHUB_APP_PRIVATE_KEY_PATH: /run/secrets/gh-app-key
Defensive patterns

Strategy: validation

Validate before calling

import os
if not os.environ.get('GITHUB_APP_ID'):
    raise RuntimeError('GITHUB_APP_ID missing — GitHub App auth will raise before any API call')

Type guard

null

Try / catch

try:
    token = await get_installation_token(inst_id)
except GitHubAppAuthError as e:
    if 'is not set' in str(e):
        raise ConfigError('GitHub App env incomplete — set GITHUB_APP_ID/_PRIVATE_KEY(_PATH)')
    raise

Prevention

When it happens

Trigger: Any code path that calls app_id() — mint_app_jwt(), installation token minting — while GITHUB_APP_ID is missing from the Gateway process environment. Typically right after enabling the GitHub App integration without completing env setup.

Common situations: GitHub App integration configured in config.yaml but env vars only set in the shell, not in the docker-compose environment or systemd unit; secrets file sourced only in interactive shells; typo in the variable name; CI running integration tests without the GitHub fixture env.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/1bfe0f1a619f405f. Report an issue: GitHub.