pathwaycom/pathway · error · ValueError

expected string key, got {type(key)}

Error message

expected string key, got {type(key)}

What it means

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.

Source

Thrown at python/pathway/internals/yaml_loader.py:26

import importlib
import io
import os
import re
import warnings
from dataclasses import dataclass, field
from types import TracebackType
from typing import Any, Callable, cast, overload

import yaml
from typing_extensions import Self

VARIABLE_TAG = "tag:pathway.com,2024:variable"


def verify_dict_keys(d: dict[object, object]) -> dict[str | Variable, object]:
    for key in d.keys():
        if not isinstance(key, str) and not isinstance(key, Variable):
            raise ValueError(f"expected string key, got {type(key)}")
    return cast(dict[str | Variable, object], d)


@dataclass(frozen=True)
class Variable:
    name: str

    def __str__(self) -> str:
        return f"${self.name}"


@dataclass(eq=False)
class Value:
    constructor: Callable[..., object] | None = None
    kwargs: dict[str | Variable, object] = field(default_factory=lambda: {})
    constructed: bool = False
    value: object = None

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Quote the keys in the YAML so they are strings: '1': foo instead of 1: foo
  2. Use string keys throughout the mapping
  3. Move numeric/boolean keys into values (e.g. options: {id: 1}) instead of using them as mapping keys

Example fix

# before
!python/pathway.io.csv
csv_settings:
  1: enabled

# after
!python/pathway.io.csv
csv_settings:
  '1': enabled
Defensive patterns

Strategy: validation

Validate before calling

def yaml_keys_are_strings(doc: dict) -> bool:
    return all(isinstance(k, str) for k in doc) and all(
        yaml_keys_are_strings(v) if isinstance(v, dict) else True for v in doc.values()
    )

Type guard

def has_only_str_keys(d: dict) -> bool:
    return all(isinstance(k, str) for k in d)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/4a6053929ec27eb2. Report an issue: GitHub.