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
- Use exactly one of 'ERROR', 'INFO', or 'DEBUG' (uppercase).
- Map unsupported levels yourself: use 'ERROR' for WARNING/CRITICAL-level output or preprocess the level string with .upper().
- 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
- Restrict offered levels in config tooling to ERROR/INFO/DEBUG.
- Normalize case (level.upper()) before passing the config through, since matching is case-sensitive.
- Map WARNING/CRITICAL to the closest supported level yourself.
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
- At most one of --create_test and --fix_tests may be…
- Cannot convert element of type
- "Cannot specify 'callable' with 'path' and 'name' for…
- Chain at missing transforms property.
- Dependencies must be a list of strings, got
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 xView on GitHub (pinned to 12126d8942)