reacherhq/check-if-email-exists · critical

Environment variable RCH_MAXIMUM_CONCURRENT_TASK_FETCH…

Error message

Environment variable RCH_MAXIMUM_CONCURRENT_TASK_FETCH should parse to usize

What it means

Identical mechanism to error 7 but for RCH_MAXIMUM_CONCURRENT_TASK_FETCH: create_job_registry parses this env var as usize with expect(), so any set-but-unparseable value panics the process during job registry creation.

Solutions

  1. Set RCH_MAXIMUM_CONCURRENT_TASK_FETCH to a plain non-negative integer (e.g. 20).
  2. Unset the variable to use the built-in default of 20.
  3. Check for stray whitespace, commas, or quotes in the value's source (env file, CI secret).
  4. Replace the expect() with graceful error handling.

Example fix

// before
RCH_MAXIMUM_CONCURRENT_TASK_FETCH=1,000
// after
RCH_MAXIMUM_CONCURRENT_TASK_FETCH=1000
Defensive patterns

Strategy: validation

Validate before calling

let max_conc_task_fetch = std::env::var("RCH_MAXIMUM_CONCURRENT_TASK_FETCH")
    .map_or(Ok(20usize), |v| v.trim().parse::<usize>().map_err(|e| anyhow!("RCH_MAXIMUM_CONCURRENT_TASK_FETCH={v:?} is not a valid usize: {e}")))?;

Type guard

fn parse_usize_env(name: &str) -> Result<Option<usize>, anyhow::Error> {
    match std::env::var(name) {
        Err(_) => Ok(None),
        Ok(v) => v.trim().parse::<usize>().map(Some).map_err(|e| anyhow!("{name}={v:?} is not a valid usize: {e}")),
    }
}

Try / catch

match std::env::var("RCH_MAXIMUM_CONCURRENT_TASK_FETCH") {
    Ok(v) => match v.trim().parse::<usize>() {
        Ok(n) => n,
        Err(e) => { eprintln!("invalid RCH_MAXIMUM_CONCURRENT_TASK_FETCH={v}: {e}"); std::process::exit(1); }
    },
    Err(_) => 20,
}

Prevention

When it happens

Trigger: RCH_MAXIMUM_CONCURRENT_TASK_FETCH is set to a non-numeric string, a negative number, or a value larger than usize::MAX when create_job_registry runs at startup.

Common situations: Misconfigured systemd/docker env files with unit suffixes or stray characters; copy-pasted values like "1,000"; conflicts with languages expecting "0" allowed while code assumes positive values (0 parses fine, so this is mostly about non-numeric input).

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


AI-assisted analysis of reacherhq/check-if-email-exists@81da93e8a4 (2026-09-11). Data as JSON: /api/errors/fc3be9584d156588. Report an issue: GitHub.

Appendix: source

Thrown at backend/src/http/v0/bulk/mod.rs:41

use std::env;

use check_if_email_exists::LOG_TARGET;
use sqlx::{Pool, Postgres};
use sqlxmq::{JobRegistry, JobRunnerHandle};
use tracing::info;

pub use task::email_verification_task;

/// Create a job registry with one task: the email verification task.
pub async fn create_job_registry(pool: &Pool<Postgres>) -> Result<JobRunnerHandle, sqlx::Error> {
	let min_task_conc = env::var("RCH_MINIMUM_TASK_CONCURRENCY").map_or(10, |var| {
		var.parse::<usize>()
			.expect("Environment variable RCH_MINIMUM_TASK_CONCURRENCY should parse to usize")
	});
	let max_conc_task_fetch = env::var("RCH_MAXIMUM_CONCURRENT_TASK_FETCH").map_or(20, |var| {
		var.parse::<usize>()
			.expect("Environment variable RCH_MAXIMUM_CONCURRENT_TASK_FETCH should parse to usize")
	});

	// registry needs to be given list of jobs it can accept
	let registry = JobRegistry::new(&[email_verification_task]);

	// create runner for the message queue associated
	// with this job registry
	let registry = registry
		// Create a job runner using the connection pool.
		.runner(pool)
		// Here is where you can configure the job runner
		// Aim to keep 10-20 jobs running at a time.
		.set_concurrency(min_task_conc, max_conc_task_fetch)
		// Start the job runner in the background.
		.run()
		.await?;

	info!(

View on GitHub (pinned to 81da93e8a4)