{"record":{"id":"4a6053929ec27eb2","repo":"pathwaycom/pathway","slug":"expected-string-key-got-type-key","errorCode":null,"errorMessage":"expected string key, got {type(key)}","messagePattern":"expected string key, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/yaml_loader.py","lineNumber":26,"sourceCode":"import importlib\nimport io\nimport os\nimport re\nimport warnings\nfrom dataclasses import dataclass, field\nfrom types import TracebackType\nfrom typing import Any, Callable, cast, overload\n\nimport yaml\nfrom typing_extensions import Self\n\nVARIABLE_TAG = \"tag:pathway.com,2024:variable\"\n\n\ndef verify_dict_keys(d: dict[object, object]) -> dict[str | Variable, object]:\n    for key in d.keys():\n        if not isinstance(key, str) and not isinstance(key, Variable):\n            raise ValueError(f\"expected string key, got {type(key)}\")\n    return cast(dict[str | Variable, object], d)\n\n\n@dataclass(frozen=True)\nclass Variable:\n    name: str\n\n    def __str__(self) -> str:\n        return f\"${self.name}\"\n\n\n@dataclass(eq=False)\nclass Value:\n    constructor: Callable[..., object] | None = None\n    kwargs: dict[str | Variable, object] = field(default_factory=lambda: {})\n    constructed: bool = False\n    value: object = None\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/yaml_loader.py#L8-L44","documentation":"ValueError raised by verify_dict_keys while loading a Pathway YAML config: every key in a mapping passed to a !tag constructor must be a string or an unresolved ${variable}. YAML natively supports ints, bools and nulls as keys, but Pathway's connector constructors only accept string keys.","triggerScenarios":"YAML like '1: foo', 'true: bar', 'null: baz', or ~: value under a !python.pathway... mapping node. Any non-string YAML scalar key (int, float, bool, None, date) inside a Pathway-constructed mapping triggers this.","commonSituations":"Porting a generic YAML config to Pathway's YAML API; numeric or boolean keys left from a dict-based config; typo where the value was placed as the key; anchors/merge producing non-string keys.","solutions":["Quote the keys in the YAML so they are strings: '1': foo instead of 1: foo","Use string keys throughout the mapping","Move numeric/boolean keys into values (e.g. options: {id: 1}) instead of using them as mapping keys"],"exampleFix":"# before\n!python/pathway.io.csv\ncsv_settings:\n  1: enabled\n\n# after\n!python/pathway.io.csv\ncsv_settings:\n  '1': enabled","handlingStrategy":"validation","validationCode":"def yaml_keys_are_strings(doc: dict) -> bool:\n    return all(isinstance(k, str) for k in doc) and all(\n        yaml_keys_are_strings(v) if isinstance(v, dict) else True for v in doc.values()\n    )","typeGuard":"def has_only_str_keys(d: dict) -> bool:\n    return all(isinstance(k, str) for k in d)","tryCatchPattern":null,"preventionTips":["Quote all mapping keys in Pathway YAML files","Validate YAML with a lint step before deployment","Keep configuration keys strings by design"],"tags":["pathway","yaml","configuration","parsing"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}