risingwavelabs/risingwave · error · ConnectorError

Field ' ' is not allowed to be altered on the fly for sink

Error message

Field '{field}' is not allowed to be altered on the fly for sink: {sink_name}

What it means

Generated-code guard for `ALTER SINK`: the requested field is absent from SINK_ALLOW_ALTER_ON_FLY_FIELDS (or the JdbcSink-specific list) for that sink connector, so altering it without recreating the sink is rejected. Generic whitelist check over the field name.

Solutions

  1. Alter only fields in the sink's allow_alter_on_fly registry.
  2. Recreate the sink with the desired configuration instead of altering it.
  3. Fix field name casing/typos.
  4. Register the field as alterable and regenerate if it should be supported.

Example fix

// before
check_sink_allow_alter_on_fly_fields("kafka", &["topic".into()])?;
// after
DROP SINK s;
CREATE SINK s INTO kafka WITH (topic = 'new-topic');
Defensive patterns

Strategy: validation

Validate before calling

fn can_alter_sink(sink: &str, field: &str) -> bool {
    let allowed = if sink == JdbcSink::SINK_NAME {
        CONNECTION_ALLOW_ALTER_ON_FLY_FIELDS.get(JdbcSink::SINK_NAME)
    } else {
        sink_properties::sink_name_to_config_type_name(sink)
            .and_then(|t| SINK_ALLOW_ALTER_ON_FLY_FIELDS.get(t))
    };
    allowed.map(|f| f.contains(&field.to_string())).unwrap_or(false)
}

Try / catch

match check_sink_allow_alter_on_fly_fields(sink, &fields) {
    Err(e) => return Err(sql_error::unsupported(&format!("sink alter rejected: {e}"))),
    Ok(()) => proceed(),
}

Prevention

When it happens

Trigger: Validating an ALTER on a sink field not present in SINK_ALLOW_ALTER_ON_FLY_FIELDS for the given sink type.

Common situations: Attempting to change immutable sink options (e.g. Kafka topic, JDBC table) live; field-name typo; trying schema evolution the sink does not support.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/connector/src/with_options_test.rs:871

    let allowed_fields = if sink_name == JdbcSink::SINK_NAME {{
        CONNECTION_ALLOW_ALTER_ON_FLY_FIELDS.get(JdbcSink::SINK_NAME)
    }} else {{
        // Convert sink name to the type name key
        let Some(type_name) = sink_properties::sink_name_to_config_type_name(sink_name) else {{
            return Err(ConnectorError::from(anyhow::anyhow!(
                "Unknown sink connector: {{sink_name}}"
            )));
        }};
        SINK_ALLOW_ALTER_ON_FLY_FIELDS.get(type_name)
    }};
    let Some(allowed_fields) = allowed_fields else {{
        return Err(ConnectorError::from(anyhow::anyhow!(
            "No allow_alter_on_fly fields registered for sink: {{sink_name}}"
        )));
    }};
    for field in fields {{
        if !allowed_fields.contains(field) {{
            return Err(ConnectorError::from(anyhow::anyhow!(
                "Field '{{field}}' is not allowed to be altered on the fly for sink: {{sink_name}}"
            )));
        }}
    }}
    Ok(())
}}
"#,
        source_entries = source_entries,
        sink_entries = sink_entries
    )
}

View on GitHub (pinned to 6469eb736d)