{"record":{"id":"1ffd91ef5f2d745f","repo":"risingwavelabs/risingwave","slug":"no-properties-provided-to-update","errorCode":null,"errorMessage":"No properties provided to update","messagePattern":"No properties provided to update","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/ctl/src/cmd_impl/meta/source_props.rs","lineNumber":41,"sourceCode":"///\n/// This is a safe way to update source properties that:\n/// 1. Pauses the source (already commits state)\n/// 2. Updates catalog and propagates changes\n/// 3. Optionally resets split assignments\n/// 4. Resumes the source\npub async fn alter_source_properties_safe(\n    context: &CtlContext,\n    source_id: u32,\n    props_json: String,\n    reset_splits: bool,\n) -> Result<()> {\n    let meta_client = context.meta_client().await?;\n\n    let props: HashMap<String, String> =\n        serde_json::from_str(&props_json).context(\"Failed to parse props as JSON object\")?;\n\n    if props.is_empty() {\n        return Err(anyhow!(\"No properties provided to update\"));\n    }\n\n    println!(\"=== ALTER SOURCE PROPERTIES (SAFE) ===\");\n    println!(\"Source ID: {}\", source_id);\n    println!(\"Properties to update: {:?}\", props);\n    println!(\"Reset splits: {}\", reset_splits);\n    println!();\n\n    println!(\"WARNING: This operation will pause the source during the update.\");\n    if reset_splits {\n        println!(\"WARNING: Split reset requested - this may cause data duplication or loss!\");\n    }\n    println!();\n\n    meta_client\n        .alter_source_properties_safe(\n            SourceId::from(source_id),\n            props.into_iter().collect(),","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/ctl/src/cmd_impl/meta/source_props.rs#L23-L59","documentation":"Guard in alter_source_properties_safe: after parsing the props JSON object, an empty map means there is nothing to update, so the operation is rejected rather than performing a pointless pause/update/resume cycle on the source. The faulty input is an empty JSON object `{}` for props.","triggerScenarios":"Calling the alter-source-properties command with a JSON object that has no keys (e.g. '{}') or JSON that deserializes to an empty map.","commonSituations":"Empty string or '{}' from a variable that was never populated; forgetting the props argument in a script.","solutions":["Pass a non-empty JSON object of properties, e.g. '{\"broker.endpoint\":\"host:9092\"}'","Check the variable feeding props_json is populated before invoking the command","If no change is intended, skip calling the alter command entirely"],"exampleFix":"// before\nalter_source_properties_safe(ctx, id, \"{}\", false)\n// after\nalter_source_properties_safe(ctx, id, \"{\\\"broker.endpoint\\\":\\\"broker:9092\\\"}\", false)","handlingStrategy":"validation","validationCode":"let props: HashMap<String, String> = serde_json::from_str(&props_json)?;\nif props.is_empty() {\n    return Err(anyhow!(\"props must contain at least one key\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check props JSON is non-empty before invoking the command","Fail fast in scripts when variables are unpopulated"],"tags":["rust","risingwave","cli","empty-input"],"backgroundTag":"empty-required-field","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}