{"record":{"id":"98cc80b5c21957bd","repo":"risingwavelabs/risingwave","slug":"no-offsets-provided-to-inject","errorCode":null,"errorMessage":"No offsets provided to inject","messagePattern":"No offsets provided to inject","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/ctl/src/cmd_impl/meta/source_props.rs","lineNumber":108,"sourceCode":"    Ok(())\n}\n\n/// Inject specific offsets into source splits.\n///\n/// WARNING: This is an UNSAFE operation that may cause data duplication or loss!\n/// Use with extreme caution and only when you know the exact offsets needed.\npub async fn inject_source_offsets(\n    context: &CtlContext,\n    source_id: u32,\n    offsets_json: String,\n) -> Result<()> {\n    let meta_client = context.meta_client().await?;\n\n    let offsets: HashMap<String, String> =\n        serde_json::from_str(&offsets_json).context(\"Failed to parse offsets as JSON object\")?;\n\n    if offsets.is_empty() {\n        return Err(anyhow!(\"No offsets provided to inject\"));\n    }\n\n    println!(\"=== INJECT SOURCE OFFSETS (UNSAFE) ===\");\n    println!(\"Source ID: {}\", source_id);\n    println!(\"Offsets to inject:\");\n    for (split_id, offset) in &offsets {\n        println!(\"  {} -> {}\", split_id, offset);\n    }\n    println!();\n    println!(\"WARNING: This is an UNSAFE operation!\");\n    println!(\"Injecting incorrect offsets WILL cause data duplication or loss!\");\n    println!(\"Make sure you know the exact offsets needed before proceeding.\");\n    println!();\n\n    let applied_splits = meta_client\n        .inject_source_offsets(SourceId::from(source_id), offsets)\n        .await?;\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/ctl/src/cmd_impl/meta/source_props.rs#L90-L126","documentation":"Guard in inject_source_offsets: the offsets JSON parsed to an empty map, so there are no split offsets to inject. The unsafe offset-injection operation refuses to run with no data rather than truncating source state for nothing.","triggerScenarios":"Calling the inject-offsets command with '{}' or a JSON string that parses to an empty map.","commonSituations":"Script variable for offsets left empty; copying the command template without filling offsets.","solutions":["Provide a non-empty JSON map like '{\"0\":\"offset-123\"}' keyed by split id","Verify the offsets variable is populated before running this unsafe command","Use the safe alter-source-properties path if you only meant to update connector properties"],"exampleFix":"// before\ninject_source_offsets(ctx, id, \"{}\")\n// after\ninject_source_offsets(ctx, id, \"{\\\"split-0\\\":\\\"kafka-offset-42\\\"}\")","handlingStrategy":"validation","validationCode":"let offsets: HashMap<String, String> = serde_json::from_str(&offsets_json)?;\nif offsets.is_empty() {\n    return Err(anyhow!(\"offsets must contain at least one split\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Populate offsets from a listing of the source's splits","Never run unsafe inject commands with template placeholders"],"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"}