ErrLookup › Background articles › "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE)
"must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE)
"must be positive", "Invalid task", "Unsupported action", "Invalid recurse value", and "INVALID_PARAMETER_VALUE" are all faces of the same error family: a library checked a parameter you passed against its allowed set or range and refused it before doing any work. These fail-fast validation errors appear at construction, config-load, or API-dispatch time across matplotlib, MLflow, Chroma, LiteLLM, Puppet, and many others. This article explains why libraries validate eagerly, the recurring trigger patterns (zero used as a sentinel, wrong vocabulary, case and whitespace mismatches, data-derived values that drift to zero), and how to fix and prevent them.
Distilled from 127 documented records across 28 repositories.
Background
This family lives at the boundary between caller and library. Somewhere between accepting your argument and starting real work, the library runs a check: is this value in the allowed set, in the allowed range, or of the allowed shape? If not, it raises immediately — a Python ValueError or MlflowException with INVALID_PARAMETER_VALUE, a Ruby ArgumentError or Puppet::Error, a TypeScript ApiError with status 400, or a plain language-specific Exception. The defining trait is eagerness: the error fires at construction or dispatch time (constructing a RateLimiter with requests_per_second=0, entering a wan_memory_optimization context, calling set_xscale) or at request-parse time (parsePrintOptions rejecting a bad orientation or kind), not deep inside the operation. MLflow's docs for diffusers.save_model state the rationale plainly: fail fast so you don't get an unusable config that only blows up later at load or inference time.
Why the checks exist varies by mechanism. Some parameters are mathematically degenerate at invalid values: matplotlib's symlog linscale and asinh linear_width collapse or invert their transforms at zero, a token-bucket rate limiter with a non-positive refill rate never refills, and a chunking helper with a non-positive limit would loop forever — so the guard is a theorem, not a style choice. Others are whitelists: Danbooru's period param accepts exactly eight singular granularities, OpenProject's hierarchy endpoint accepts exactly 'parent' or 'child', Hiera's merge option accepts a fixed set of strings, LiteLLM's Nova Canvas builder knows four task types. Here the error is a vocabulary mismatch — you used a word from a neighboring API (tidy's recurse doesn't accept file's 'remote'; Chroma's HF sparse EF doesn't accept Nomic's 'search_document' task names). A third shape is structural: zeroclaw's checkout requires the branch to sanitize to exactly one token, MLflow's dataset constructor names must start with 'load_' or 'from_', and evaluate() with predictions requires dataframe-like data because named columns are meaningless for arrays.
From the caller's side, these errors usually mean one of a handful of situations. Zero or a non-positive number was used where only strictly positive values are valid — often because 0 was intended to mean 'disabled' or 'no limit', a convention most of these APIs explicitly do not honor (use enabled=False, omit the parameter, or use a different mode instead). A value computed from data or config drifted to an edge case: a linear_width computed from a constant signal is exactly 0, len(endpoints) * base_rps evaluates to 0, a computed chunk limit goes negative after subtracting a header. Or a string value is subtly wrong: wrong case ('LandScape', 'PDF'), a plural ('days' instead of 'day'), a synonym ('jpg' instead of 'jpeg'), a trailing space, a hyphen where an underscore belongs ('request-review' vs 'request_review'), or a symbol where a string is expected (Puppet's :true vs 'true').
The family varies across libraries mainly in error surface and strictness. Python libraries tend toward ValueError or a typed MlflowException carrying an INVALID_PARAMETER_VALUE code; web backends return 400 with the bad value interpolated into the message; older or plainer codebases raise bare Exceptions with a formatted string. Strictness also differs: matplotlib's bw_method matches 'scott' case-insensitively, while most string whitelists are exact and case-sensitive. Some checks sit behind type hints that don't actually enforce anything at runtime — Chroma's task parameter is typed as a Literal but an invalid value surfaces only on the first add/query — which is why the same family can appear as a confusingly late error rather than an immediate one.
Common causes
- Zero or a negative number used as a 'disabled' or 'unlimited' sentinel. Many parameters are strictly positive by mathematical necessity — matplotlib's linscale and linear_width, MLflow's requests_per_second, sglang's shift, InvokeAI's activation_chunk_size, Chroma's aggregation k, deepagents' chunk limit. These APIs have no 0/-1 convention; disabling is done via a separate flag (enabled=False), omitting the parameter, or a different mode.
- Data- or config-derived values that drift to 0 or negative. A linear_width computed from a constant signal is exactly 0; len(endpoints) * base_rps can be 0; a chunk limit of max_len minus header length can hit zero; integer division and empty collections produce 0. The library receives a plausible-looking number that is degenerate.
- Value from a neighboring API's vocabulary. Whitelists are per-API: 'search_document' is Nomic's task name, not Chroma's HF sparse one; 'remote' is valid for Puppet file recurse but not tidy; 'follows'/'blocks' belong to OpenProject's general relations endpoint, not the hierarchy one; COLOR_GUIDED_GENERATION is an image-generation task, not an image-edit one. Copy-pasted configs carry invalid values across boundaries.
- Case, whitespace, plural, or spelling mismatches in string enums. Most whitelists are exact: 'days' vs 'day', 'jpg' vs 'jpeg', 'PDF' vs 'pdf', 'LandScape' vs 'landscape', a trailing space, 'request-review' vs 'request_review', 'outpainting' vs 'OUTPAINTING'. A few APIs are case-insensitive (matplotlib's bw_method), but assuming that universally is unsafe.
- Wrong type where a shape check exists. Puppet's hasstatus setter accepts true/false and 'true'/'false' but not the symbol :true; numpy arrays are not numbers for GaussianKDE's bw_method; Path objects are not strings for base_model; a numpy array has no named predictions column for mlflow.evaluate. Runtime validation is stricter than the type hints suggest.
- Blank, empty, or missing-by-default values forwarded from config or user input. Empty branch strings, base_model="" or None, empty query_config dicts missing their 'task' key, and unset env vars that parse to 0 all get forwarded instead of defaulted or rejected at the boundary. The check that should have happened at config-load time fires inside the library instead.
- Parameter combinations that are individually valid but jointly incoherent. MLflow's archive_existing_versions=True only makes sense when the target stage is Production or Staging; pos_label must be an element of label_list (same value and dtype); a scheduler shift of 0 inherited by per-modality overrides fails later. Validating one parameter in isolation misses these cross-parameter constraints.
What usually fixes it
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
Go deeper
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Documented occurrences
- 'linscale' must be positive (matplotlib/matplotlib)
- Invalid branch specification (zeroclaw-labs/zeroclaw)
- Invalid task: {self.task} (chroma-core/chroma)
- Unsupported action "%s". (phacility/phabricator)
- Invalid task: {self.query_config.get('task')} (chroma-core/chroma)
- Multipart chunk size {_readable_size(chunk_size)} must be in range: {_readable_size(_AWS_MIN_CHUNK_SIZE)} to {_readable_size(_AWS_MAX_CHUNK_SIZE)}. (mlflow/mlflow)
- invalid period: #{period} (danbooru/danbooru)
- Failed to fetch ${input} with status ${resp.status}: ${resp.statusText} (chroma-core/chroma)
- Scale parameter 'linear_width' must be strictly positive (matplotlib/matplotlib)
- Unrecognized value for request 'merge' parameter: '%{merge}' (puppetlabs/puppet)
- Invalid 'hasstatus' value #{value.inspect} (puppetlabs/puppet)
- Invalid page orientation: ${orientation} (hcengineering/platform)
- `bw_method` should be 'scott', 'silverman', a scalar or a callable (matplotlib/matplotlib)
- Failed to set GC thresholds: {e} (BerriAI/litellm)
- requests_per_second must be positive (mlflow/mlflow)
- INVALID_PARAMETER_VALUE: If predictions is specified, data must be one of the following types, or an MLflow Dataset that represents one of the following types: {supported_predictions_dataset_types}. (mlflow/mlflow)
- numpoints must be > 0; it was %d (matplotlib/matplotlib)
- Invalid task_type={task_type}. Expected one of={hf_tasks_embeddings} (BerriAI/litellm)
- Invalid recurse value %{value} (puppetlabs/puppet)
- chunk limit must be positive (langchain-ai/deepagents)
…and 107 more across the corpus — use search.
Honest provenance: generated on 2026-08-29 from AI-assisted analysis of the linked records. See how records are made.