apache/beam · error · ValueError

f'Unknown log level not in

Error message

f'Unknown log level {level} not in {list(log_levels.keys())}'

What it means

The YAML Log transform maps a language-agnostic log level to logging calls, but recognizes only ERROR, INFO, and DEBUG; the level given matches none of them, so it rejects the configuration rather than silently choosing a default.

Solutions

  1. Use exactly one of 'ERROR', 'INFO', or 'DEBUG' (uppercase).
  2. Map unsupported levels yourself: use 'ERROR' for WARNING/CRITICAL-level output or preprocess the level string with .upper().
  3. Extend the config upstream so only supported levels are offered.

Example fix

# before
- type: LogForLevel
  config:
    level: warning
# after
- type: LogForLevel
  config:
    level: ERROR
Defensive patterns

Strategy: validation

Validate before calling

VALID_LOG_LEVELS = {'ERROR', 'INFO', 'DEBUG'}
def validate_log_level(level):
    if str(level).upper() not in VALID_LOG_LEVELS:
        raise ValueError(f'level must be one of {sorted(VALID_LOG_LEVELS)}')

Type guard

def is_supported_log_level(level):
    return isinstance(level, str) and level in {'ERROR', 'INFO', 'DEBUG'}

Try / catch

try:
    level_fn = {'ERROR': logging.error, 'INFO': logging.info, 'DEBUG': logging.debug}[level]
except KeyError:
    logging.warning('Unsupported level %r, falling back to INFO', level)
    level_fn = logging.info

Prevention

When it happens

Trigger: Setting level: WARNING, level: error (lowercase), level: FATAL, or any other value outside {'ERROR','INFO','DEBUG'} in the YAML logging transform config.

Common situations: Authors assume all Python logging levels are supported (WARNING/CRITICAL are not mapped), or use lowercase level names.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/9b9609f674b0140d. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/yaml/yaml_provider.py:1197

    The output of this transform is a copy of its input for ease of use in
    chain-style pipelines.

    Args:
      level: one of ERROR, INFO, or DEBUG, mapped to a corresponding
        language-specific logging level
      prefix: an optional identifier that will get prepended to the element
        being logged
    """
    # Keeping this simple to be language agnostic.
    # The intent is not to develop a logging library (and users can always do)
    # their own mappings to get fancier output.
    log_levels = {
        'ERROR': logging.error,
        'INFO': logging.info,
        'DEBUG': logging.debug,
    }
    if level not in log_levels:
      raise ValueError(
          f'Unknown log level {level} not in {list(log_levels.keys())}')
    logger = log_levels[level]

    def to_loggable_json_recursive(o):
      if isinstance(o, (str, bytes)):
        return str(o)
      elif callable(getattr(o, '_asdict', None)):
        return to_loggable_json_recursive(o._asdict())
      elif isinstance(o, Mapping) and callable(getattr(o, 'items', None)):
        return {str(k): to_loggable_json_recursive(v) for k, v in o.items()}
      elif isinstance(o, Iterable):
        return [to_loggable_json_recursive(x) for x in o]
      else:
        return o

    def log_and_return(x):
      logger(prefix + json.dumps(to_loggable_json_recursive(x)))
      return x

View on GitHub (pinned to 12126d8942)