pathwaycom/pathway · error · ValueError

The MQTT topic to publish to must not contain the wildcard c

Error message

The MQTT topic to publish to must not contain the wildcard characters '+' or '#' (got {topic!r}); wildcards are only allowed when reading (subscribing).

What it means

In MQTT, '+' and '#' are subscription wildcards — a client cannot publish to them. pw.io.mqtt.write therefore rejects a string topic containing '+' or '#' with a ValueError echoing the offending topic and clarifying that wildcards are only valid on the read (subscribe) side.

Source

Thrown at python/pathway/io/mqtt/__init__.py:333

    ...     format="plaintext",
    ...     value=table.owner,
    ... )

    Finally, if you'd like the topic to be dynamic and depend on the owner of the pet,
    you can specify this column definition as the topic:

    >>> pw.io.mqtt.write(
    ...     table,
    ...     "mqtt://localhost:1883/?client_id=test",
    ...     topic=table.owner,
    ...     format="json",
    ... )
    """
    if isinstance(topic, str):
        if topic == "":
            raise ValueError("The MQTT topic to publish to must not be empty.")
        if "+" in topic or "#" in topic:
            raise ValueError(
                "The MQTT topic to publish to must not contain the wildcard characters "
                f"'+' or '#' (got {topic!r}); wildcards are only allowed when reading "
                "(subscribing)."
            )
    output_format = MessageQueueOutputFormat.construct(
        table,
        format=format,
        delimiter=delimiter,
        value=value,
        topic_name=topic if isinstance(topic, ColumnReference) else None,
    )
    table = output_format.table

    data_storage = api.DataStorage(
        storage_type="mqtt",
        path=uri,
        topic=topic if isinstance(topic, str) else None,
        topic_name_index=output_format.topic_name_index,

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Publish to a concrete topic without wildcards: topic='sensors/kitchen/temperature'
  2. Use separate config keys for read filters and write topics
  3. For per-row topics, pass a column: topic=table.room (ColumnReference is not checked for wildcards as it is data-driven)

Example fix

# before
TOPIC = "sensors/+/temperature"  # wildcard shared with reader
pw.io.mqtt.write(t, "mqtt://localhost:1883", topic=TOPIC)

# after
WRITE_TOPIC = "sensors/kitchen/temperature"
pw.io.mqtt.write(t, "mqtt://localhost:1883", topic=WRITE_TOPIC)
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(topic, str) and any(w in topic for w in "+#"):
    raise ValueError(f"{topic!r} contains publish-illegal wildcards; use a concrete topic")

Type guard

def is_publishable_topic(topic) -> bool:
    if isinstance(topic, pw.ColumnReference):
        return True
    return isinstance(topic, str) and topic != "" and not any(w in topic for w in "+#")

Try / catch

try:
    pw.io.mqtt.write(table, uri, topic=topic)
except ValueError as e:
    if "wildcard characters" in str(e):
        raise ValueError("Publish topics cannot use +/#; those are subscribe-only filters") from e
    raise

Prevention

When it happens

Trigger: Reusing a subscription-style filter as the publish topic: pw.io.mqtt.write(table, uri, topic='sensors/+/temperature') or a shared TOPIC constant used by both read and write calls.

Common situations: One config value (e.g. MQTT_TOPIC='devices/#') shared between a reader and writer; copy-pasting an example subscribe filter into a publish call; dynamic topic columns mistakenly passed as strings.

Related errors


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