{"record":{"id":"837ce53b56ff518a","repo":"oraios/serena","slug":"invalid-yaml-in-path-values-that-start-with","errorCode":null,"errorMessage":"Invalid YAML in {path}: values that start with `*` must be quoted. This often happens in `ignored_paths` when using gitignore-style globs like `\"**/bin/**\"` or `\"**/obj/**\"`.","messagePattern":"Invalid YAML in (.+?): values that start with `\\*` must be quoted\\. This often happens in `ignored_paths` when using gitignore-style globs like `\"\\*\\*/bin/\\*\\*\"` or `\"\\*\\*/obj/\\*\\*\"`\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/serena/util/yaml.py","lineNumber":78,"sourceCode":"# item comment indices: (post key, pre key, post value, pre value)\nITEM_COMMENT_INDEX_BEFORE = 1  # (pre-key; must be a list of CommentToken at this index)\nITEM_COMMENT_INDEX_AFTER = 2  # (post-value; must be an instance of CommentToken at this index)\n\n\ndef load_yaml(path: str, comment_normalisation: YamlCommentNormalisation = YamlCommentNormalisation.NONE) -> CommentedMap:\n    \"\"\"\n    :param path: the path to the YAML file to load\n    :param comment_normalisation: the comment normalisation to apply after loading\n    :return: the loaded commented map\n    \"\"\"\n    with open(path, encoding=SERENA_FILE_ENCODING) as f:\n        yaml = _create_yaml(preserve_comments=True)\n        try:\n            commented_map: CommentedMap | None = yaml.load(f)\n        except Exception as e:\n            msg = str(e)\n            if \"undefined alias\" in msg:\n                raise ValueError(\n                    f\"Invalid YAML in {path}: values that start with `*` must be quoted. \"\n                    \"This often happens in `ignored_paths` when using gitignore-style globs like \"\n                    '`\"**/bin/**\"` or `\"**/obj/**\"`.'\n                ) from e\n            raise\n    if commented_map is None:  # ruamel returns None for empty documents, but we want an empty CommentedMap\n        commented_map = CommentedMap()\n    normalise_yaml_comments(commented_map, comment_normalisation)\n    return commented_map\n\n\ndef normalise_yaml_comments(commented_map: CommentedMap, comment_normalisation: YamlCommentNormalisation) -> None:\n    \"\"\"\n    Applies the given comment normalisation to the given commented map in-place.\n\n    :param commented_map: the commented map whose comments are to be normalised\n    :param comment_normalisation: the comment normalisation to apply\n    \"\"\"","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/util/yaml.py#L60-L96","documentation":"load_yaml parses a YAML file with ruamel and raises ValueError when the parser fails with an 'undefined alias' error. YAML treats a leading `*` as an alias reference, so unquoted gitignore-style glob values like **/bin/** are parsed as (undefined) YAML aliases rather than strings. Serena raises this specific message because this most commonly happens in `ignored_paths` settings.","triggerScenarios":"Calling load_yaml (directly or via from_config_file/_load_yaml_dict) on a config file where a scalar value starts with `*` and is not quoted, e.g. `ignored_paths: [**/bin/**]`.","commonSituations":"Users hand-editing serena config files and copying gitignore glob patterns into ignored_paths without quoting; tools generating YAML that omit quotes around values starting with `*`.","solutions":["Open the file named in the error and quote every value that starts with `*`, e.g. `\"**/bin/**\"`.","Re-run the command that loaded the config; the ValueError reports the exact path.","If the alias is intentional, define the corresponding YAML anchor (`&name`) before the alias."],"exampleFix":"// before\nignored_paths:\n  - **/bin/**\n  - **/obj/**\n// after\nignored_paths:\n  - \"**/bin/**\"\n  - \"**/obj/**\"","handlingStrategy":"validation","validationCode":"import re\nfrom pathlib import Path\n\ndef validate_yaml_globs(config_path: str) -> list[str]:\n    issues = []\n    for i, line in enumerate(Path(config_path).read_text().splitlines(), 1):\n        stripped = line.split('#', 1)[0].rstrip()\n        if re.search(r':\\s+\\*', stripped) or re.search(r\"-\\s+\\*\", stripped):\n            issues.append(f\"line {i}: unquoted value starting with '*': {stripped.strip()}\")\n    return issues","typeGuard":"def is_safe_yaml_scalar(value: str) -> bool:\n    return not value.lstrip().startswith('*')","tryCatchPattern":"try:\n    cfg = load_yaml(path)\nexcept ValueError as e:\n    if 'must be quoted' in str(e):\n        fix_unquoted_globs(path)  # quote all values starting with '*'\n        cfg = load_yaml(path)\n    else:\n        raise","preventionTips":["Always quote glob patterns in YAML configs, even when not strictly required.","Generate ignored_paths programmatically with a YAML dumper that quotes strings starting with '*'.","Add a pre-commit lint rule that flags `*: ` and `- *` patterns in YAML files."],"tags":["yaml","config","parsing"],"backgroundTag":"yaml-alias-parse-error","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}