{"record":{"id":"65114b58f8558555","repo":"apache/beam","slug":"ambiguous-expression-type-perhaps-missing-quoting-expr","errorCode":null,"errorMessage":"Ambiguous expression type (perhaps missing quoting?): {expr}","messagePattern":"Ambiguous expression type \\(perhaps missing quoting\\?\\): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/yaml/yaml_mapping.py","lineNumber":403,"sourceCode":"    return lambda row: getattr(row, fn_spec)\n  else:\n    return _as_callable(\n        list(input_schema.keys()), fn_spec, msg, language, input_schema)\n\n\ndef _as_callable(original_fields, expr, transform_name, language, input_schema):\n  if isinstance(expr, str):\n    expr = {'expression': expr}\n\n  # Extract original type from upstream pcoll when doing simple mappings\n  original_type = input_schema.get(expr.get('expression'), None)\n  if expr in original_fields:\n    language = \"python\"\n\n  # TODO(yaml): support an imports parameter\n  # TODO(yaml): support a requirements parameter (possibly at a higher level)\n  if not isinstance(expr, dict):\n    raise ValueError(\n        f\"Ambiguous expression type (perhaps missing quoting?): {expr}\")\n  explicit_type = expr.pop('output_type', None)\n  _check_mapping_arguments(transform_name, **expr)\n\n  if language == \"javascript\":\n    func = _expand_javascript_mapping_func(original_fields, **expr)\n  elif language in (\"python\", \"generic\", None):\n    func = _expand_python_mapping_func(original_fields, **expr)\n  else:\n    raise ValueError(\n        f'Unknown language for mapping transform: {language}. '\n        'Supported languages are \"javascript\" and \"python.\"')\n\n  if explicit_type:\n    if isinstance(explicit_type, str):\n      explicit_type = {'type': explicit_type}\n    beam_type = json_utils.json_type_to_beam_type(explicit_type)\n    validator = _validator(beam_type)","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/yaml/yaml_mapping.py#L385-L421","documentation":"After normalizing string specs to {'expression': ...}, `_as_callable` requires the field spec to be a dict. If a spec is neither a string nor a dict (e.g. an int, bool, or list from YAML), it is ambiguous—likely a bare value that YAML parsed as a non-string because it was not quoted—and the transform refuses to guess.","triggerScenarios":"Writing a MapToFields field config whose value is an unquoted YAML scalar that parses as int/bool/float (e.g. `field: 42` or `field: yes` or `field: null`), or passing a list/dict-shape mismatch to _as_callable.","commonSituations":"YAML type-coercion surprises: `count: 1` intended as the string '1', `flag: yes` intended as string 'yes', or copy-pasted JSON with numbers as expression values.","solutions":["Quote the value in the YAML file so it parses as a string: `field: \"42\"`.","Ensure each field's value is either a plain string expression or a dict with expression/callable/path keys.","Run the pipeline with the YAML validator (beam_yaml linting) to catch these before execution."],"exampleFix":"# before (YAML parses 42 as int)\nfields:\n  count: 42\n# after\nfields:\n  count: \"42\"","handlingStrategy":"validation","validationCode":"for name, spec in fields.items():\n    assert isinstance(spec, (str, dict)), f'field {name}: quote the value or use a dict spec'","typeGuard":"def is_valid_field_spec(spec) -> bool:\n    if isinstance(spec, str):\n        return True\n    return isinstance(spec, dict) and bool(spec)","tryCatchPattern":"try:\n    run_pipeline(yaml_spec)\nexcept ValueError as e:\n    if 'Ambiguous expression type' in str(e):\n        raise ConfigError('unquoted YAML scalar in field spec') from e","preventionTips":["Quote all expression strings in YAML: use \"...\" around values","Never rely on YAML auto-typing for field values (42, yes, null)","Validate YAML specs before submitting pipelines"],"tags":["yaml","yaml-parsing","beam-yaml","config"],"backgroundTag":"yaml-parse-error","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}