ErrLookup › Background articles › Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained
Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained
"Invalid option value" errors — messages like "must be one of [SKIP, FAIL]", "is not a valid type", "only allows '.', '-' and alphanumeric characters", or "invalid ... value" — fire when a library rejects a configuration or call option that falls outside its hard-coded vocabulary. Developers meet this family at generator, parser, test-framework, and CLI boundaries: the value is checked eagerly before any real work starts, and the fix is almost always correcting the value to the library's exact accepted set rather than working around the check.
Distilled from 78 documented records across 23 repositories.
Background
This family lives at the trust boundary between caller and library. When a library exposes an option, it usually has a closed vocabulary — an enum, a whitelist of symbols, a regex over strings, or a numeric range — and it validates eagerly: the check runs during option parsing, query construction, or builder setup, before rendering, generation, network work, or test execution begins. That is why these errors feel abrupt: nothing partial has happened yet, and re-running with a corrected value is safe. The producing layer varies (a Java generator's processOpts, a Ruby gem's DSL evaluation, a TypeScript builder synchronously assembling a tool definition), but the caller-side shape is the same: an exception naming the offending value, often with the supported list appended.
The mechanism splits into three sub-shapes across the family. Enum membership is the most common: openapi-generator parsing declarativeInterfaceReactiveMode with a case-sensitive valueOf() that knows exactly coroutines and reactor; Capybara accepting only :all and :visible for text queries; Bundler matching --trust-policy against CamelCase RubyGems security policy names. Shape validation covers numeric guards — caveman requiring safe positive integers for token wallets and timeouts, Angular rejecting timeout values below 1 or non-integers because the platform would silently drop them — and character-set regexes like openapi-generator's suffix options, where dots and dashes are fine in file names but forbidden in class names. Vocabulary confusion is a recurring trigger inside the mechanism: GNU cp --preserve words pasted into Hadoop's -p letters, Playwright's polling: 'interval' passed to k6, and 0.x option symbols carried into a 2.x API with a smaller whitelist all fail because two tools share a concept but not a vocabulary.
Comparison is typically exact. Case matters in openapi-generator's valueOf parses and Vagrant's tgz/zip list, though some libraries normalize by trimming and upper-casing before matching. Messages vary in helpfulness: many append the full supported set (Bundler, brakeman, openapi-generator's enum lists), while others — like openapi-generator's Xojo "invalid enum property naming option" text that actually refers to the serialization library — carry copy-paste artifacts or misleading labels (the server generator's apiFileSuffix reported as 'Service'). A recurring trap is that sentinel values often do not exist: NONE is invalid for optionalNonNullPropertyJsonSetterNulls, 0 does not mean 'disabled' for timeouts or compaction knobs, and the documented disable path is omitting the option entirely, which is library-specific behavior worth checking per record.
Common causes
- Case or spelling mismatch against a case-sensitive enum. Passing COROUTINES instead of coroutines to openapi-generator, 'Runtime' instead of 'runtime' to caveman's bedrock endpoint, or high-security instead of HighSecurity to Bundler. Comparison is exact in most libraries; only some normalize casing before matching.
- Porting vocabulary from a different tool or API version. Playwright's polling: 'interval' rejected by k6, GNU cp --preserve words rejected by Hadoop's -p letter codes, and commonmarker 0.x symbols like :SAFE rejected by the 2.x-backed github/markup all fail because the concept exists but the accepted words differ.
- Guessed or invented values. Symbols like :invisible or :obscured for Capybara text queries (only :all and :visible exist), match: :smartest instead of :smart, or NONE passed to an option that reserves no 'off' sentinel. The error usually lists what was actually accepted.
- Illegal characters in string options. Underscores, dots, or dashes in openapi-generator suffix options: file suffixes allow only '.', '-' and alphanumerics; class suffixes allow alphanumerics only because the value becomes a TypeScript identifier.
- Values from config, ENV, or serialization boundaries arrive as the wrong type. Strings like "60" for Bundler's integer cooldown, arrays for Prism's command_line string, string numbers for caveman's integer knobs, or JSON-derived symbols never converted with .to_sym. Explicit nil can also bypass defaults that only apply to absent keys.
- Computed values that produce 0, NaN, fractions, or out-of-range numbers. Budget arithmetic yielding 0 or NaN for caveman's wallet and cap options, totalTokens / 3 producing a float, seconds passed where milliseconds are expected (0.5), or values beyond the safe-integer range. Numeric guards require positive safe integers.
- Using 0 or a sentinel to mean 'disabled' when none exists. timeoutMs: 0, maxCompactions: 0, and maxSubagentInvocations: 0 all throw; the supported disable path is omitting the option or removing the relevant tools from the definition.
- Passing extension or per-item names through a global option. Extension symbols like :tasklist belong in github/markup's commonmarker_exts, not commonmarker_opts; per-property JsonInclude policies like ALWAYS belong in per-property spec extensions, not the global four-value option.
What usually fixes it
- Read the error message's own value list first — many records (Bundler, brakeman, openapi-generator enums) append the authoritative accepted set, and per-generator/per-tool lists differ even within one project.
- Correct the value to the exact accepted form: right case, right spelling, right type (Symbol vs String, integer vs string, joined string vs array). Re-running is safe because validation happens before any real work.
- When the intent is 'off', 'unlimited', or 'default', omit the option instead of passing 0, NONE, or a guessed sentinel — but check the specific record, since which sentinels exist is library-specific.
- Coerce and validate at the boundary where values enter your code: .to_sym for serialized symbols, .to_i or Number() for numeric strings, Math.floor or Math.round for computed values, and whitelist checks for ENV- and config-derived enums.
- Keep option values in shared constants or a single config source rather than ad-hoc literals at call sites, and add a table-driven test or CI lint that exercises each supported option so drift fails in CI, not production.
- During major-version migrations (e.g. cmark-gfm 0.x to commonmarker 2.x), grep for old option constants and delete or remap ones with no new equivalent instead of passing them through.
Go deeper
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Documented occurrences
- unknown commonmarker option: #{opt.inspect} (github/markup)
- %s file suffix only allows '.', '-' and alphanumeric characters. (OpenAPITools/openapi-generator)
- Invalid value for additional property 'declarativeInterfaceReactiveMode'. Supported values are {values}. (OpenAPITools/openapi-generator)
- {} must be one of [NON_NULL, NON_EMPTY, NON_DEFAULT, NONE] but was: {} (OpenAPITools/openapi-generator)
- #{@type} is not a valid type for a text query (teamcapybara/capybara)
- caveman agent: subagent maxTokens must be a positive integer (JuliusBrussee/caveman)
- No attribute for {} (apache/hadoop)
- {} is an invalid enum property naming option. Please choose from: (OpenAPITools/openapi-generator)
- Invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(', ')} (teamcapybara/capybara)
- {} must be one of [SKIP, FAIL] but was: {} (OpenAPITools/openapi-generator)
- invalid raise_error value: #{value} (ruby/ruby)
- bedrock endpoint must be runtime or mantle (JuliusBrussee/caveman)
- %s file suffix only allows '.', '-' and alphanumeric characters. (OpenAPITools/openapi-generator)
- No attribute for " + symbol (apache/hadoop)
- caveman agent: subagent maxCostUsd must be positive (JuliusBrussee/caveman)
- invalid forwarding value: #{forward} (ruby/ruby)
- Expected `cooldown` to be a non-negative integer, got #{cooldown.inspect} (ruby/ruby)
- frame waitForFunction: %w (grafana/k6)
- %s class suffix only allows alphanumeric characters. (OpenAPITools/openapi-generator)
- caveman agent: tool timeoutMs must be a positive integer (JuliusBrussee/caveman)
…and 58 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.