astrid-runtime/astrid · error
must be exactly 'file' or 'stderr', got
Error message
{DAEMON_LOG_TARGET_ENV} must be exactly 'file' or 'stderr', got {} What it means
The daemon reads its log-target configuration from an environment variable (DAEMON_LOG_TARGET_ENV) and only accepts the exact values 'file' or 'stderr'. daemon_log_config bails with this error when the variable is set to anything else, including misspellings, mixed case, whitespace, or other targets like 'stdout'.
Solutions
- Set the env var to exactly `file` or `stderr` (lowercase, no whitespace).
- Unset the variable entirely to get the default (file logging).
- Print/echo the variable in the shell to catch hidden whitespace or quoting issues.
- Fix wrapper scripts/systemd unit files that export an unsupported value.
Example fix
// before export ASTRID_DAEMON_LOG_TARGET=stdout // after export ASTRID_DAEMON_LOG_TARGET=stderr # or 'file', or unset for default
Defensive patterns
Strategy: validation
Validate before calling
fn log_target_valid() -> bool {
match std::env::var("ASTRID_DAEMON_LOG_TARGET") {
Err(_) => true,
Ok(v) => v == "file" || v == "stderr",
}
} Try / catch
match daemon_log_config() {
Ok(cfg) => cfg,
Err(e) if e.to_string().contains("must be exactly 'file' or 'stderr'") => {
eprintln!("{e:#}; falling back to default file logging");
astrid_telemetry::LogConfig::default()
}
Err(e) => return Err(e),
} Prevention
- Only use the exact lowercase values 'file' or 'stderr'.
- Prefer unsetting the variable to relying on a custom value for the default.
- Trim/validate the value in wrapper scripts and systemd units before export.
- Avoid 'stdout' — it is not a supported target.
When it happens
Trigger: Setting DAEMON_LOG_TARGET_ENV to any value other than the exact strings "file" or "stderr" before starting the daemon.
Common situations: Typoed value ("files", "File", "stderr "); scripts exporting "stdout" expecting it to be supported; quoting mistakes leaving stray characters in the value; docs drift after the option was narrowed to two values.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- ASTRID_WORKSPACE_STATE_DIR must be valid UTF-8
- Failed to resolve Astrid home
- Admin request timed out after
- an Astrid daemon appears to be running but its uplink is…
- an Astrid daemon appears to be running but its uplink is…
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/e7eb3568f08f2ce0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-daemon/src/lib.rs:105
"debug".clone_into(&mut lc.level);
}
lc
} else {
let level = if verbose { "debug" } else { "info" };
astrid_telemetry::LogConfig::new(level).with_format(astrid_telemetry::LogFormat::Compact)
};
log_config.target = match target_override {
None => astrid_telemetry::LogTarget::File(astrid_home.log_dir()),
Some(target) if target == std::ffi::OsStr::new("file") => {
astrid_telemetry::LogTarget::File(astrid_home.log_dir())
},
Some(target) if target == std::ffi::OsStr::new("stderr") => {
log_config.ansi = false;
astrid_telemetry::LogTarget::Stderr
},
Some(target) => {
anyhow::bail!(
"{DAEMON_LOG_TARGET_ENV} must be exactly 'file' or 'stderr', got {}",
std::path::Path::new(target).display()
)
},
};
Ok(log_config)
}
#[cfg(unix)]
fn init_logging(log_config: &astrid_telemetry::LogConfig) {
if let Err(e) = astrid_telemetry::setup_logging(log_config) {
eprintln!("Failed to initialize logging: {e}");
}
}
#[cfg(unix)]
fn defer_file_logging_until_kernel_admission(
astrid_home: &astrid_core::dirs::AstridHome,View on GitHub (pinned to affd8760f4)