zed-industries/zed · error · RuntimeError

SLACK_WEBHOOK_GUILD_INTERNAL is not set

Error message

SLACK_WEBHOOK_GUILD_INTERNAL is not set

What it means

send_slack reads SLACK_WEBHOOK_GUILD_INTERNAL from the environment and refuses to operate without it: the guild board posts its summary through that Slack incoming webhook. This is a deployment/configuration error — the process environment (usually a CI secret) does not define the variable at the moment the script wants to notify.

Source

Thrown at script/github-guild-board.py:400

def escape_slack(text):
    # Escape Slack's control characters (&, <, >) so free text like issue/PR
    # titles and comment bodies renders literally instead of being interpreted
    # as a link or @-mention. send_slack can't do this wholesale because its own
    # messages legitimately contain <url|text> links and *bold* markup.
    # quote=False keeps it to Slack's three characters (no " or ' escaping).
    return html.escape(text or "", quote=False)


def slack_link(url, text):
    # The single way to embed a titled link, so the title is always escaped
    # without every caller having to remember to do it.
    return f"<{url}|{escape_slack(text)}>"


def send_slack(text):
    webhook = os.environ.get("SLACK_WEBHOOK_GUILD_INTERNAL")
    if not webhook:
        raise RuntimeError("SLACK_WEBHOOK_GUILD_INTERNAL is not set")
    message = f"{random.choice(ZEDGAR_QUIPS)} {text}"
    response = requests.post(
        webhook,
        json={
            "text": message,
            "blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": message}}],
        },
        timeout=30,
    )
    if response.status_code != 200:
        raise RuntimeError(
            f"Slack webhook returned {response.status_code}: {response.text[:200]}"
        )


def parse_dt(value):
    return datetime.fromisoformat(value.replace("Z", "+00:00"))

View on GitHub (pinned to bc538def45)

Solutions

  1. Create the secret in repo/org settings and map it in the workflow step: env: SLACK_WEBHOOK_GUILD_INTERNAL: ${{ secrets.SLACK_WEBHOOK_GUILD_INTERNAL }}
  2. Locally: export SLACK_WEBHOOK_GUILD_INTERNAL=https://hooks.slack.com/services/T.../B.../... before running
  3. Validate required env vars at script startup so the failure names the missing config immediately
  4. Consider making the Slack post non-fatal (log and continue) if the board update itself already succeeded

Example fix

// before
def send_slack(text):
    webhook = os.environ.get("SLACK_WEBHOOK_GUILD_INTERNAL")
    if not webhook:
        raise RuntimeError("SLACK_WEBHOOK_GUILD_INTERNAL is not set")

// after
def main():
    if not os.environ.get("SLACK_WEBHOOK_GUILD_INTERNAL"):
        raise SystemExit("SLACK_WEBHOOK_GUILD_INTERNAL is not set; cannot post the guild board summary")
Defensive patterns

Strategy: validation

Validate before calling

def required_env_present(names: list[str]) -> bool:
    return all(os.environ.get(n) for n in names)

Type guard

def slack_webhook_is_configured() -> bool:
    return bool(os.environ.get("SLACK_WEBHOOK_GUILD_INTERNAL"))

Try / catch

try:
    send_slack(summary)
except RuntimeError as exc:
    if "is not set" in str(exc):
        log(f"Skipping Slack notification: {exc}")
    else:
        raise

Prevention

When it happens

Trigger: The CI workflow step omits env: SLACK_WEBHOOK_GUILD_INTERNAL; the secret was renamed or never created in the repo/org settings; running the script locally without exporting the variable.

Common situations: Workflow yaml edited and the env block dropped; secret-name typo (e.g. SLACK_WEBHOOK vs SLACK_WEBHOOK_GUILD_INTERNAL); contributors running scripts locally without the internal webhook.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/43931a4110f01547. Report an issue: GitHub.