zed-industries/zed · critical

invalid release channel {}

Error message

invalid release channel {}

What it means

The release_channel crate resolves Zed's distribution channel (dev, nightly, preview, stable) once per process. The name comes from the runtime env var ZED_RELEASE_CHANNEL in debug builds, otherwise from the compile-time env var or the zed/RELEASE_CHANNEL file. ReleaseChannel::from_str accepts exactly dev, nightly, preview, stable; any other string makes the RELEASE_CHANNEL LazyLock panic on first access (crates/release_channel/src/lib.rs:40). Note the env-var path does not trim or lowercase, so 'Stable' or a trailing newline also fails.

Source

Thrown at crates/release_channel/src/lib.rs:40

/// library, it vendors each crate separately and builds it in isolation, which
/// makes the `include_str!` fail.
///
/// The build script checks for `$ZED_RELEASE_CHANNEL` and emits the `cfg`
#[cfg(__do_not_set_zed_release_channel)]
fn compile_time_release_channel_name() -> String {
    env!("ZED_RELEASE_CHANNEL").trim().to_string()
}

#[cfg(not(__do_not_set_zed_release_channel))]
fn compile_time_release_channel_name() -> String {
    include_str!("../../zed/RELEASE_CHANNEL").trim().to_string()
}

#[doc(hidden)]
pub static RELEASE_CHANNEL: LazyLock<ReleaseChannel> =
    LazyLock::new(|| match ReleaseChannel::from_str(&RELEASE_CHANNEL_NAME) {
        Ok(channel) => channel,
        _ => panic!("invalid release channel {}", *RELEASE_CHANNEL_NAME),
    });

/// The app identifier for the current release channel, Windows only.
#[cfg(target_os = "windows")]
pub fn app_identifier() -> &'static str {
    match *RELEASE_CHANNEL {
        ReleaseChannel::Dev => "Zed-Editor-Dev",
        ReleaseChannel::Nightly => "Zed-Editor-Nightly",
        ReleaseChannel::Preview => "Zed-Editor-Preview",
        ReleaseChannel::Stable => "Zed-Editor-Stable",
    }
}

/// The Git commit SHA that Zed was built at.
#[derive(Clone, Eq, Debug, PartialEq)]
pub struct AppCommitSha(String);

struct GlobalAppCommitSha(AppCommitSha);

View on GitHub (pinned to f4178619ac)

Solutions

  1. Set ZED_RELEASE_CHANNEL to a supported value (dev, nightly, preview, or stable, lowercase, no extra whitespace) or unset it so the checked-in zed/RELEASE_CHANNEL file is used.
  2. For debug builds, check your current shell: printenv ZED_RELEASE_CHANNEL — the value is read at runtime, not only build time.
  3. Verify zed/RELEASE_CHANNEL contains exactly one of the four names if the env var is not set.
  4. If a custom channel is genuinely needed, extend ReleaseChannel::from_str and all match arms instead of feeding an unknown string.

Example fix

# before
ZED_RELEASE_CHANNEL=beta cargo run
# panics: invalid release channel beta

# after
unset ZED_RELEASE_CHANNEL
cargo run
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
case "${ZED_RELEASE_CHANNEL:-}" in
  ""|dev|nightly|preview|stable) ;;
  *) echo "invalid ZED_RELEASE_CHANNEL: '$ZED_RELEASE_CHANNEL'" >&2; exit 1 ;;
esac
cargo build "$@"

Prevention

When it happens

Trigger: Running a debug build with ZED_RELEASE_CHANNEL set to anything outside dev/nightly/preview/stable (e.g. beta, local, 'stable\n', 'Stable'); building a release binary with the compile-time env var or zed/RELEASE_CHANNEL file containing such a value. The panic is lazy: it fires on first touch of RELEASE_CHANNEL, e.g. updater checks, telemetry, or app-id setup.

Common situations: CI or distro packaging scripts exporting their own channel name; forks renaming the channel without extending the enum; an env var leaking from an unrelated build step in the same shell; editing zed/RELEASE_CHANNEL while experimenting.

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/a526c18eeb74bab3. Report an issue: GitHub.