{"record":{"id":"afbc6da088d4d7d4","repo":"risingwavelabs/risingwave","slug":"invalid-scan-startup-mode-accept-earliest-latest","errorCode":null,"errorMessage":"invalid scan.startup.mode, accept earliest/latest/timestamp","messagePattern":"invalid scan\\.startup\\.mode, accept earliest/latest/timestamp","errorType":"validation","errorClass":"ConnectorError","httpStatus":null,"severity":"error","filePath":"src/connector/src/source/kinesis/source/reader.rs","lineNumber":95,"sourceCode":"        assert!(splits.len() == 1);\n\n        let split = splits.into_iter().next().unwrap();\n\n        let next_offset = match &split.next_offset {\n            KinesisOffset::None => match &properties.scan_startup_mode {\n                None => KinesisOffset::Earliest,\n                Some(mode) => match mode.as_str() {\n                    \"earliest\" => KinesisOffset::Earliest,\n                    \"latest\" => KinesisOffset::Latest,\n                    \"timestamp\" => {\n                        if let Some(ts) = &properties.start_timestamp_millis {\n                            KinesisOffset::Timestamp(*ts)\n                        } else {\n                            bail!(\"scan.startup.timestamp.millis is required\");\n                        }\n                    }\n                    _ => {\n                        bail!(\"invalid scan.startup.mode, accept earliest/latest/timestamp\")\n                    }\n                },\n            },\n            next_offset => next_offset.to_owned(),\n        };\n\n        if !matches!(next_offset, KinesisOffset::Timestamp(_))\n            && properties.start_timestamp_millis.is_some()\n        {\n            // cannot bail! here because all new split readers will fail to start if user set 'scan.startup.mode' to 'timestamp'\n            tracing::warn!(\n                \"scan.startup.mode needs to be set to 'timestamp' if you want to start with a specific timestamp, starting shard {} from the beginning\",\n                split.id()\n            );\n        }\n\n        let stream_name = properties.common.stream_name.clone();\n        let client = properties.common.build_client().await?;","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/source/kinesis/source/reader.rs#L77-L113","documentation":"During Kinesis source construction, `new` matches `scan.startup.mode` against the three accepted values `earliest`, `latest`, and `timestamp`. Any other string falls into the wildcard arm and `bail!`s with this message listing the accepted values.","triggerScenarios":"Setting WITH option `scan.startup.mode` to a value other than earliest/latest/timestamp, e.g. ' Earliest' (case/space), 'from_timestamp', 'oldest', or a typo like 'ealiest'.","commonSituations":"Migrating configs from Kafka connector (`scan.startup.mode='earliest_offset'`), copy-paste from other systems where modes are named differently, or manual typos in CREATE SOURCE DDL.","solutions":["Set `scan.startup.mode` to exactly one of 'earliest', 'latest', or 'timestamp' (lowercase, no spaces).","If coming from Kafka-style configs, replace values like 'earliest_offset'/'latest_offset' with 'earliest'/'latest'.","Remove the option entirely to use the default startup mode."],"exampleFix":"// before\nWITH (\n  connector = 'kinesis',\n  stream_name = 'events',\n  scan.startup.mode = 'earliest_offset'\n)\n// after\nWITH (\n  connector = 'kinesis',\n  stream_name = 'events',\n  scan.startup.mode = 'earliest'\n)","handlingStrategy":"validation","validationCode":"// Validate scan.startup.mode against the allowed set before creating the source\nconst VALID: [&str; 3] = [\"earliest\", \"latest\", \"timestamp\"];\nlet mode = props.get(\"scan.startup.mode\").map(|s| s.as_str()).unwrap_or(\"latest\");\nif !VALID.contains(&mode) {\n    return Err(anyhow!(\"invalid scan.startup.mode '{mode}', must be one of earliest/latest/timestamp\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only lowercase 'earliest', 'latest', 'timestamp' — no offsets-style suffixes from Kafka configs.","Trim/normalize user input before writing the WITH option.","Copy options only from Kinesis-specific documentation, not Kafka connector examples."],"tags":["kinesis","startup-mode","invalid-enum"],"backgroundTag":"invalid-enum-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"}