ErrLookup › Background articles › "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys
"X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys
"vertex_project and vertex_location are required", "must be set", "cannot be empty", "No application program defined" - these are missing-required-config errors: a library refuses to proceed because a mandatory setting was absent at the point it was needed. Developers meet this family when wiring SDKs, proxies, and frameworks (litellm, EasyWeChat, Hadoop, Yii2, k6 and others), typically in fresh CI runners or containers where env vars and config keys that existed on the dev machine never arrive. This article explains the mechanism shared by all of them, the recurring causes, and fixes that work across the family.
Distilled from 81 documented records across 18 repositories.
Background
This family sits at the configuration-validation layer of a library, between object construction and the first real operation. Libraries enforce it as a fail-fast guard: instead of sending empty credentials, building a malformed URL, or silently doing nothing, they raise a ValueError, IllegalArgumentException, RuntimeException, or framework exception naming the missing key. The check can run eagerly at construction (EasyWeChat Config::checkMissingKeys, Yii2 Theme::applyTo, ruflo ConformanceRunner) or lazily at first use (Yii2 FileDependency at cache evaluation, ruflo proofSigningKey on the first session:create event, EasyWeChat Server::getToken on the first callback), which is why some variants surprise you well after startup.
From the caller's side the error looks uniform: the message names one or more required keys, and the fix is to supply them via one of the library's resolution paths. Records show a consistent resolution ladder - per-call params, environment variables, module-level or process-level defaults, config files, and secret stores. litellm's Vertex AI handlers are the canonical example: project and location resolve from call params, VERTEXAI_PROJECT/VERTEXAI_LOCATION env vars, module attributes, or secrets, and the ValueError fires only when every rung comes up empty. EasyWeChat, Watsonx, Purview, and Hadoop's ABFS follow the same shape with different key names.
The family varies most in what counts as "missing" and what else interacts with the check. EasyWeChat checks key existence, not non-empty values, while many others use falsy checks where an empty string still triggers the error. Some checks can be bypassed by an alternative: litellm's api_base short-circuits project/location resolution on some handler paths - but not on the Imagen image-edit path, where project/location are needed to build the URL regardless; Watsonx's "deployment/<id>" model prefix skips the project check entirely. A distinct subgroup (litellm's CodeInterpreterInterception and Ovalix guards, Hadoop's MiniKdc) fires only when invariants are broken after construction - config mutated mid-session - which signals a library bug or misuse rather than a plain omission.
Common causes
- Clean environment in CI or containers. Config that worked on a dev laptop (env vars in .bashrc) fails in CI runners, Docker, or serverless deployments where the environment is stripped or only credentials like GOOGLE_APPLICATION_CREDENTIALS are set. Credentials alone are not enough when the library also needs identifiers like project/location to build a URL.
- Per-call params omitted in favor of ambient env. Relying on environment variables instead of passing required values explicitly on each call. litellm, Watsonx, and EasyWeChat records all show calls failing because no per-call param was supplied and no env var was present.
- Key spelling or casing mismatch. 'appid' vs 'app_id', 'filename' vs 'fileName', 'hadoop.pipes.executable' vs 'mapreduce.pipes.executable', tenantId vs tenant_id. Frameworks silently leave the real property null, and serde or YAML configs default unknown keys to None, so the check fails with the correctly-spelled name in the message.
- Wrong nesting or partial config merge. The key exists but not where the library reads it: a sibling of litellm_params instead of inside it, only the global instead of the account-specific Hadoop key, or a merged config where the entry was dropped. The value never reaches the resolving code.
- Paired requirements and conditional keys. Some keys are required only in combination: a custom base_url demands a model (sure's Anthropic and OpenAI settings), enabling enableProofChain demands proofSigningKey, enabling an Ovalix hook demands its matching checkpoint id, user-bound SAS demands a token provider class. Config sources for the pair often diverge so one side is empty.
- Empty-string or null values counting as missing. Many checks are falsy-based, so an env var set to empty string (some shells do this), bucket_name: '', or a null value placed via put() still trips the guard even though the key technically exists.
- Config mutated after construction. The library validated config at init but someone cleared or removed it before use - litellm's sandbox_config set to None mid-session, MiniKdc's transport key removed before start(), guardrail ids cleared across proxy reloads. These indicate broken invariants rather than ordinary omission.
- Bypass expectations that do not hold everywhere. Developers assume api_base or a similar override replaces the required config, but behavior is handler-specific: litellm's api_base skips project/location on Gemini and image-generation paths yet the Imagen image-edit path still requires them to build the URL.
What usually fixes it
- Read the error message first: across the family it names the exact missing keys and often the env var or param that supplies each - add them via the library's documented resolution path (per-call param, env var, module default, or config file).
- Pass required values explicitly per call or at process start instead of relying on ambient environment; assert required env vars and config keys at startup or in CI so missing config fails the build, not the first request.
- Check exact key spelling, casing, and nesting against the library's schema - snake_case vs camelCase, old vs new key names, and keys placed at the wrong config level all leave the real property unset while the typo'd one looks present.
- Treat conditional and paired requirements as one unit: submit base_url together with model, enable flags together with their secrets, and hook enables together with their ids in a single config change.
- Verify whether an override (api_base, fixed-token mode, deployment/<id> model prefix) legitimately skips the check - but confirm it per handler path, since the records show the same library bypassing the check on one path and enforcing it on another.
- Treat config objects as immutable after construction; if configuration must change, rebuild the component so its validation re-runs rather than mutating a live instance.
Go deeper
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Documented occurrences
- vertex_project and vertex_location are required for Vertex AI (BerriAI/litellm)
- vertex_project and vertex_location are required for Vertex AI (BerriAI/litellm)
- CodeInterpreterInterception: no sandbox available to run code. (BerriAI/litellm)
- vertex_project and vertex_location are required for Vertex AI (BerriAI/litellm)
- bucket_name must be provided for GCS destination (BerriAI/litellm)
- vertex_project and vertex_location are required for Vertex AI (BerriAI/litellm)
- Ovalix: application_id or checkpoint_id not resolved (BerriAI/litellm)
- "%s" cannot be empty.\r\n (w7corp/easywechat)
- "%s" must be set for user-bound SAS auth type. (apache/hadoop)
- CodeInterpreterInterception: no sandbox available. Provide a sandbox_config or configure a sandbox tool resolvable via sandbox_tool_name. (BerriAI/litellm)
- No more entry in " + f (apache/hadoop)
- bucket_name must be provided for S3 destination (BerriAI/litellm)
- Blockchain execution transaction limits are required: allowed_token_pairs, slippage_bps, max_slippage_bps, max_order_amount, deadline_seconds, max_quote_age_blocks, receipt_timeout_secs (nautechsystems/nautilus_trader)
- Missing Ovalix guardrail configuration errors: {errors} (BerriAI/litellm)
- TestRunID is required (grafana/k6)
- prompt_id is required for Arize Phoenix prompt manager (BerriAI/litellm)
- No application program defined. (apache/hadoop)
- Error: Watsonx project_id and space_id not set. Set WX_PROJECT_ID or WX_SPACE_ID in environment variables or pass in as a parameter. (BerriAI/litellm)
- DIRECTIVE_MISSING_SELECTOR: Directive ${clazz.name.text} has no selector, please add it! (angular/angular)
- Need to set transport! (apache/hadoop)
…and 61 more across the corpus — use search.
Honest provenance: generated on 2026-08-25 from AI-assisted analysis of the linked records. See how records are made.