{"record":{"id":"c432df2bae9a8653","repo":"risingwavelabs/risingwave","slug":"invalid-scan-startup-mode-accept-earliest-latest-c432df","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/nats/source/reader.rs","lineNumber":78,"sourceCode":"        // We guarantee the split num always align with parallelism\n        assert_eq!(splits.len(), 1);\n        let split = splits.into_iter().next().unwrap();\n        let split_id = split.split_id;\n        let start_position = match &split.start_sequence {\n            NatsOffset::None => match &properties.scan_startup_mode {\n                None => NatsOffset::Earliest,\n                Some(mode) => match mode.as_str() {\n                    \"latest\" => NatsOffset::Latest,\n                    \"earliest\" => NatsOffset::Earliest,\n                    \"timestamp\" | \"timestamp_millis\" /* backward-compat */ => {\n                        if let Some(ts) = &properties.start_timestamp_millis {\n                            NatsOffset::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            // We have record on this Nats Split, contains the last seen offset (seq id) or reply subject\n            // We do not use the seq id as start position anymore,\n            // but just let the reader load from durable consumer on broker.\n            start_position => start_position.to_owned(),\n        };\n\n        let mut config = consumer::pull::Config {\n            ..Default::default()\n        };\n        properties.set_config(&mut config)?;\n\n        let (consumer, client) = properties\n            .common\n            .build_consumer(\n                properties.stream.clone(),","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/source/nats/source/reader.rs#L60-L96","documentation":"The NATS source reader only accepts 'earliest', 'latest', or 'timestamp' as scan.startup.mode; any other value is rejected at reader construction. This guards against typos and unsupported startup strategies reaching the consumer.","triggerScenarios":"Creating a NATS source with `scan.startup.mode` set to a value outside {earliest, latest, timestamp, timestamp_millis} — e.g. 'beginning', 'default', 'EARLIEST', or 'from_timestamp'.","commonSituations":"Copying Kafka-style startup options ('earliest_offset'/'latest_offset') into a NATS source; case-sensitivity mistakes; typos like 'earlies'.","solutions":["Set scan.startup.mode to exactly one of 'earliest', 'latest', or 'timestamp' (lowercase).","If migrating from Kafka defaults, use 'earliest' or 'latest' instead of Kafka-specific names.","For timestamp mode, also supply scan.startup.timestamp.millis."],"exampleFix":"// before\nWITH (connector = 'nats', scan.startup.mode = 'beginning')\n// after\nWITH (connector = 'nats', scan.startup.mode = 'earliest')","handlingStrategy":"validation","validationCode":"const VALID: [&str; 3] = [\"earliest\", \"latest\", \"timestamp\"];\nif let Some(mode) = props.get(\"scan.startup.mode\") {\n    if !VALID.contains(&mode.as_str()) && mode != \"timestamp_millis\" {\n        return Err(format!(\"invalid scan.startup.mode: {mode}\"));\n    }\n}","typeGuard":"fn is_valid_nats_startup_mode(mode: &str) -> bool {\n    matches!(mode, \"earliest\" | \"latest\" | \"timestamp\" | \"timestamp_millis\")\n}","tryCatchPattern":"match source.create().await {\n    Err(e) if e.to_string().contains(\"invalid scan.startup.mode\") => eprintln!(\"use earliest/latest/timestamp\"),\n    other => other,\n}","preventionTips":["Keep a shared constant list of valid startup modes per connector.","Use schema-driven WITH-clause validation in tooling before submitting DDL.","Never copy Kafka-specific startup mode names into NATS sources."],"tags":["nats","config","validation","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-14T16:17:12.679Z"}