coleam00/Archon · critical

GitHub adapter misconfigured: both App mode (GITHUB_APP_ID)

Error message

GitHub adapter misconfigured: both App mode (GITHUB_APP_ID) and PAT mode (GITHUB_TOKEN) are configured. Pick one — unset GITHUB_TOKEN for App mode, or unset GITHUB_APP_ID for PAT mode.

What it means

startServer fail-fast check for the GitHub adapter's dual authentication modes: App mode (GITHUB_APP_ID) and PAT mode (GITHUB_TOKEN). selectGitHubAuthMode() returns a 'conflict' result when both are present, and startServer throws rather than silently preferring one, because an operator who copied half a config wouldn't know which credential is actually being used.

Source

Thrown at packages/server/src/index.ts:415

  let github: GitHubAdapter | null = null;
  let githubAppAuthProvider: IGitHubAppAuthProvider | null = null;
  let gitea: GiteaAdapter | null = null;
  let gitlab: GitLabAdapter | null = null;
  let discord: DiscordAdapter | null = null;
  let slack: SlackAdapter | null = null;
  let slackBridge: SlackWorkflowBridge | null = null;

  if (!opts.skipPlatformAdapters) {
    // Check that at least one platform is configured
    const hasTelegram = Boolean(process.env.TELEGRAM_BOT_TOKEN);
    const hasDiscord = Boolean(process.env.DISCORD_BOT_TOKEN);
    // GitHub adapter: dual-mode (App vs PAT). Fail fast if both are configured —
    // silently preferring one would create 3am debugging sessions for an operator
    // who copy-pasted half a config and didn't realise the other half was already
    // set in /etc/archon/.env. (PRD: "fail-fast on misconfig".)
    const ghAuthMode = selectGitHubAuthMode(process.env);
    if (ghAuthMode.kind === 'conflict') {
      throw new Error(ghAuthMode.message);
    }
    const hasGitHub = ghAuthMode.kind !== 'none';
    const hasGitea = Boolean(
      process.env.GITEA_URL && process.env.GITEA_TOKEN && process.env.GITEA_WEBHOOK_SECRET
    );
    const hasGitLab = Boolean(process.env.GITLAB_TOKEN && process.env.GITLAB_WEBHOOK_SECRET);

    if (!hasTelegram && !hasDiscord && !hasGitHub && !hasGitea && !hasGitLab) {
      getLog().warn('no_platform_adapters_configured');
    }

    if (ghAuthMode.kind === 'app') {
      // Locals avoid `!` non-null assertions: hasGitHubApp already guarantees
      // GITHUB_APP_ID and WEBHOOK_SECRET are set, but the linter can't infer that.
      const appId = process.env.GITHUB_APP_ID;
      const webhookSecret = process.env.WEBHOOK_SECRET;
      if (!appId || !webhookSecret) {
        throw new Error('GitHub App mode misconfigured: GITHUB_APP_ID and WEBHOOK_SECRET required');

View on GitHub (pinned to 0773b97458)

Solutions

  1. Remove/comment GITHUB_TOKEN from the env file to run in GitHub App mode, or remove GITHUB_APP_ID (+ its App-only vars) to run in PAT mode.
  2. Run `archon setup` to reconfigure the GitHub adapter cleanly so only one mode's variables are written.
  3. Inspect the resolved environment (`printenv | grep GITHUB`) in the actual process context (systemd unit, container) — the conflict may come from a second env source.
  4. Restart the server after unsetting the variable; startup env is only read once.

Example fix

# before (.env)
GITHUB_APP_ID=Iv1.xxxx
GITHUB_TOKEN=ghp_xxx
# after: App mode only
GITHUB_APP_ID=Iv1.xxxx
# GITHUB_TOKEN removed
Defensive patterns

Strategy: validation

Validate before calling

const vars = readEnvFiles(['/etc/archon/.env']);
const both = Boolean(vars.GITHUB_APP_ID) && Boolean(vars.GITHUB_TOKEN);
if (both) throw new Error('Unset GITHUB_TOKEN (App mode) or GITHUB_APP_ID (PAT mode) before starting.');

Try / catch

try {
  await startServer(config);
} catch (e) {
  if (/both App mode .* and PAT mode .* are configured/i.test(e?.message ?? '')) {
    logFatal('GitHub adapter misconfigured: keep only GITHUB_APP_ID or GITHUB_TOKEN.');
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: The server environment (e.g. /etc/archon/.env) defines both GITHUB_APP_ID and GITHUB_TOKEN when `serveCommand` calls startServer.

Common situations: An operator previously ran PAT mode and later added GitHub App credentials (or vice versa) without removing the old variable; copy-pasting a full example .env that contains both blocks; migrating from PAT to App mode per docs and forgetting `unset GITHUB_TOKEN`.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/f87cda1f0ef4d014. Report an issue: GitHub.