{"record":{"id":"c773be40cbdc4e28","repo":"risingwavelabs/risingwave","slug":"since-timestamp-should-not-be-specified-when-no-sn","errorCode":null,"errorMessage":"since_timestamp should not be specified when no snapshot backfill","messagePattern":"since_timestamp should not be specified when no snapshot backfill","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/stream/stream_manager.rs","lineNumber":671,"sourceCode":"            upstream_fragment_downstreams,\n            init_split_assignment,\n            definition: definition.clone(),\n            streaming_job: streaming_job.clone(),\n            job_type,\n            create_type,\n            database_resource_group,\n            fragment_backfill_ordering,\n            cdc_table_snapshot_splits,\n            locality_fragment_state_table_mapping,\n            is_serverless: is_serverless_backfill,\n            streaming_job_model,\n            replace_sink,\n            refresh_interval_sec,\n        };\n\n        let job_type = if let Some(refresh_interval_sec) = refresh_interval_sec {\n            if since_timestamp_epoch.is_some() {\n                bail!(\"since_timestamp should not be specified when no snapshot backfill\");\n            }\n            let snapshot_backfill_info = snapshot_backfill_info.ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"batch refresh materialized view must have snapshot backfill upstream\"\n                )\n            })?;\n            // Batch refresh jobs must not contain source or source-backfill nodes,\n            // because we skip split assignment resolution for them.\n            for fragment in info.stream_job_fragments.inner.fragments.values() {\n                let mask = fragment.fragment_type_mask;\n                if mask.contains(FragmentTypeFlag::Source)\n                    || mask.contains(FragmentTypeFlag::SourceScan)\n                {\n                    bail!(\n                        \"batch refresh materialized views must not depend on sources directly; \\\n                         fragment {} has source/source-backfill nodes\",\n                        fragment.fragment_id\n                    );","sourceCodeStart":653,"sourceCodeEnd":689,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/stream/stream_manager.rs#L653-L689","documentation":"During CREATE MATERIALIZED VIEW handling, the meta node rejects a command that supplies a since_timestamp (snapshot backfill start point) for a job whose type is batch refresh without snapshot backfill semantics. since_timestamp only makes sense when a snapshot backfill upstream exists; otherwise it is meaningless input and the create is rejected via bail!.","triggerScenarios":"Running a create streaming job command where refresh_interval_sec is Some (batch refresh MV) and since_timestamp_epoch is also Some — i.e. the user specified a snapshot cutoff time for a job type that has no snapshot backfill.","commonSituations":"Users writing `CREATE MATERIALIZED VIEW ... WITH (refresh interval ..., since ...)` on an MV whose upstream is not a snapshot-backfill MV; tooling that always emits since_timestamp; SQL written for a different MV type and reused.","solutions":["Remove the `since`/since_timestamp option from the CREATE statement, or switch to a job type that supports snapshot backfill.","If a point-in-time snapshot is intended, ensure the upstream is a snapshot backfill MV so snapshot_backfill_info is present.","Update client tooling/ORM to not emit since_timestamp for interval-refresh MVs."],"exampleFix":"// before: refresh_interval_sec set AND since_timestamp_epoch set -> error\n// after: drop the since option\nCREATE MATERIALIZED VIEW mv WITH (refresh = '5 minutes') AS SELECT ...;\n-- (no `since` clause unless upstream supports snapshot backfill)","handlingStrategy":"validation","validationCode":"-- before running the create, ensure you did not set `since` on a non-snapshot-backfill/refresh MV\n-- in app code:\nif refresh_interval.is_some() && since_timestamp.is_some() && !snapshot_backfill_supported {\n    since_timestamp = None;\n}","typeGuard":null,"tryCatchPattern":"match meta.create_streaming_job(cmd).await {\n    Err(e) if e.to_string().contains(\"since_timestamp should not be specified\") => {\n        let mut cmd = cmd; cmd.since_timestamp_epoch = None;\n        meta.create_streaming_job(cmd).await\n    }\n    other => other,\n}","preventionTips":["Only add `since` clauses when the upstream MV was created with snapshot backfill.","Centralize MV DDL generation in one helper that enforces the refresh/since rules.","Read RisingWave docs on batch refresh semantics before combining WITH options."],"tags":["sql","validation","materialized-view","meta-node"],"backgroundTag":"conflicting-config-options","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}