apache/beam · error · ValueError
Ambiguous expression type (perhaps missing quoting?)
Error message
Ambiguous expression type (perhaps missing quoting?): {expr_dict} What it means
Beam YAML's validate_generic_expression checks that a mapping field's custom logic is a plain string expression or a dict like {expression: ...}. This ValueError fires when expr_dict is not a dict at all — e.g. a string, list, or scalar was passed where a language-specifying map was required. The 'perhaps missing quoting?' hint means a bare string that looks like an expression may have been YAML-parsed into a non-dict type.
Solutions
- Quote the value or structure it as a single-key map, e.g. `expression: "col + 1"` wrapped correctly so YAML yields a dict with an 'expression' key.
- Check YAML indentation — a mis-indented entry can parse as a list or scalar instead of a mapping.
- In programmatic use, verify the argument is a dict before calling: isinstance(expr_dict, dict).
- Use a language-tagged form like {expression: ..., language: python} if generic expressions are too ambiguous.
Example fix
# before (parses ambiguously / as string) mapping: output: col1 + : col2 # after custom: language: python expression: "col1 + col2"
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(cfg, dict) or list(cfg.keys()) != ['expression']:
raise ValueError('mapping custom logic must be a single-key {expression: ...} map') Type guard
def is_expr_map(v): return isinstance(v, dict) and 'expression' in v
Prevention
- Quote YAML values containing colons or braces
- Validate the pipeline config against the transform schema before submission
- Prefer the explicit {expression: ..., language: ...} form
When it happens
Trigger: Calling validate_generic_expression (via validate_generic_expressions) with a mapping entry whose value is not a dict — e.g. a YAML inline mapping parsed as a string due to unquoted special characters, or a list/tuple passed in.
Common situations: YAML config where the expression value contains colons or braces so the parser produces a string or nested structure instead of a single-key map; users writing `expression: row.a + row.b` instead of `{expression: ...}` with a language key; programmatic API misuse passing a raw string.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Invalid transform specification at
- Ambiguous expression type (perhaps missing quoting?)
- Can only use expressions on a schema'd input.
- CombineFn spec missing type
- Config for transform at
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/faf7ec86f0de51d8.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/yaml/yaml_mapping.py:112
def is_literal(expr: str) -> bool:
# Some languages have limited integer literal ranges.
if re.fullmatch(r'-?\d+?', expr) and -1 << 31 < int(expr) < 1 << 31:
return True
elif re.fullmatch(r'-?\d+\.\d*', expr):
return True
elif re.fullmatch(r'"[^\\"]*"', expr):
return True
else:
return False
def validate_generic_expression(
expr_dict: dict,
input_fields: Collection[str],
allow_cmp: bool,
error_field: str) -> None:
if not isinstance(expr_dict, dict):
raise ValueError(
f"Ambiguous expression type (perhaps missing quoting?): {expr_dict}")
if len(expr_dict) != 1 or 'expression' not in expr_dict:
raise ValueError(
"Missing language specification. "
"Must specify a language when using a map with custom logic for %s" %
error_field)
expr = str(expr_dict['expression'])
def is_atomic(expr: str):
return is_literal(expr) or expr in input_fields
if is_atomic(expr):
return
if allow_cmp:
maybe_cmp = re.fullmatch('(.*)([<>=!]+)(.*)', expr)
if maybe_cmp:
left, cmp, right = maybe_cmp.groups()View on GitHub (pinned to 12126d8942)