{"record":{"id":"dc88953aa03e0af5","repo":"risingwavelabs/risingwave","slug":"gap-interval-must-be-positive-dc8895","errorCode":null,"errorMessage":"Gap interval must be positive","messagePattern":"Gap interval must be positive","errorType":"validation","errorClass":"StreamExecutorError","httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/gap_fill.rs","lineNumber":565,"sourceCode":"            metrics,\n        } = *self;\n\n        let mut input = input.execute();\n\n        let barrier = expect_first_barrier(&mut input).await?;\n        let first_epoch = barrier.epoch;\n        yield Message::Barrier(barrier);\n        managed_state.init_epoch(first_epoch).await?;\n\n        // Calculate and validate gap interval once at initialization\n        let dummy_row = OwnedRow::new(vec![]);\n        let interval_datum = gap_interval.eval_row_infallible(&dummy_row).await;\n        let interval = interval_datum\n            .ok_or_else(|| anyhow::anyhow!(\"Gap interval expression returned null\"))?\n            .into_interval();\n\n        if interval <= Interval::from_month_day_usec(0, 0, 0) {\n            Err(anyhow::anyhow!(\"Gap interval must be positive\"))?;\n        }\n        let generation_context = GapFillGenerationContext {\n            metrics: &metrics,\n            high_amplification_threshold: high_gap_fill_amplification_threshold,\n            actor_ctx: &ctx,\n        };\n\n        let partition_by_indices = managed_state.partition_by_indices.clone();\n        let pointer_key_indices = managed_state.pointer_key_indices.clone();\n        // Interpolation re-slopes every fill, so a changed anchor changes all of them; only\n        // LOCF/NULL fills can be reused by the diff.\n        let has_interpolate = fill_columns\n            .values()\n            .any(|strategy| matches!(strategy, FillStrategy::Interpolate));\n\n        #[for_await]\n        for msg in input {\n            match msg? {","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/gap_fill.rs#L547-L583","documentation":"After evaluating the GAP interval expression, the gap-fill executor validates that the interval is strictly greater than zero. A zero or negative interval would cause an infinite/empty fill loop, so `execute_inner` fails with this anyhow error at src/stream/src/executor/gap_fill.rs:565.","triggerScenarios":"A `GAP FILL` query with `GAP INTERVAL '0 seconds'`, a negative interval, or an expression that evaluates to a non-positive interval at MV creation time.","commonSituations":"Config mistakes where a user-supplied gap parameter defaults to 0; arithmetic expressions like `end_ts - start_ts` that evaluate to zero at creation.","solutions":["Use a strictly positive INTERVAL literal, e.g. `GAP INTERVAL '1 minute'`.","If the gap comes from an expression, add GREATEST to clamp it positive: `GAP GREATEST(expr, INTERVAL '1 second')`.","Check the value bound to the gap (variable/config) before creating the materialized view."],"exampleFix":"// before\nSELECT GAP FILL(ts, INTERVAL '0 minutes') FROM t GROUP BY ts;\n// after\nSELECT GAP FILL(ts, INTERVAL '1 minute') FROM t GROUP BY ts;","handlingStrategy":"validation","validationCode":"-- Check the interval is strictly positive before use:\nSELECT gap_expr > INTERVAL '0 seconds' AS ok; -- must be true\n-- Or clamp: GREATEST(gap_expr, INTERVAL '1 second')","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"Gap interval must be positive\") => {\n        // correct the GAP literal and re-create the materialized view\n    }\n    other => other?,\n}","preventionTips":["Never pass 0 or negative INTERVALs to GAP FILL.","Clamp parameterized gaps with GREATEST(expr, INTERVAL '1 second').","Verify any externally supplied gap value before creating the MV."],"tags":["stream-executor","gap-fill","validation","interval"],"backgroundTag":"invalid-argument-value","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"}