risingwavelabs/risingwave · error

invalid topic name ' '; it must be in the format / /

Error message

invalid topic name '{}'; it must be in the format <tenant>/<namespace>/<topic>

What it means

After stripping the domain, a Pulsar topic must have exactly three slash-separated components: tenant, namespace, and topic name. parse_topic splits the remainder with splitn(3,'/') and bails when the count is not 3, since it cannot build a valid Topic struct otherwise.

Solutions

  1. Provide the topic as '<tenant>/<namespace>/<topic>', e.g. 'public/default/events'
  2. Verify the full string after '://' contains exactly two '/' separators
  3. Remove any extra path segments or append the missing namespace/tenant

Example fix

// before
let topic = parse_topic("persistent://public/events");
// after
let topic = parse_topic("persistent://public/default/events");
Defensive patterns

Strategy: validation

Validate before calling

function validatePulsarTopicPath(topic) {
  const rest = topic.split('://')[1] ?? topic;
  if (rest.split('/').length !== 3) {
    throw new Error(`topic must be <tenant>/<namespace>/<topic>: ${rest}`);
  }
}

Type guard

const isThreePartTopic = (t) => (t.split('://')[1] ?? t).split('/').length === 3;

Try / catch

try { parse_topic(input); } catch (e) { if (String(e).includes('invalid topic name')) { normalizeToTenantNsTopic(input); } else { throw e; } }

Prevention

When it happens

Trigger: Calling parse_topic with a rest path like 'tenant/topic' (missing namespace), 'tenant/namespace/topic/partition-extra', or a domain-only URL such as 'persistent://' with no path.

Common situations: Users providing only 'my-topic' with embedded slashes that do not resolve to 3 parts, truncating a copied topic URL, or accidentally appending a partition suffix that changes the part count.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/cbd24344b9cfe285. Report an issue: GitHub.

Appendix: source

Thrown at src/connector/src/source/pulsar/topic.rs:153

    }

    let parts: Vec<&str> = complete_topic.splitn(2, "://").collect();

    let domain = match parts[0] {
        PERSISTENT_DOMAIN | NON_PERSISTENT_DOMAIN => parts[0],
        _ => {
            bail!(
                "The domain only can be specified as 'persistent' or 'non-persistent'. Input domain is '{}'",
                parts[0]
            );
        }
    };

    let rest = parts[1];
    let parts: Vec<&str> = rest.splitn(3, '/').collect();

    if parts.len() != 3 {
        bail!(
            "invalid topic name '{}'; it must be in the format <tenant>/<namespace>/<topic>",
            rest
        );
    }

    let parsed_topic = Topic {
        domain: domain.to_owned(),
        tenant: parts[0].to_owned(),
        namespace: parts[1].to_owned(),
        topic: parts[2].to_owned(),
        partition_index: get_partition_index(complete_topic.as_str())?,
    };

    if parsed_topic.topic.is_empty() {
        bail!("topic name cannot be empty".to_owned());
    }

    Ok(parsed_topic)

View on GitHub (pinned to 6469eb736d)