{"record":{"id":"75e14fae77d42f60","repo":"nats-io/nats-server","slug":"expected-no-extend-for-string-value-got-s","errorCode":null,"errorMessage":"expected 'no_extend' for string value, got '%s'","messagePattern":"expected 'no_extend' for string value, got '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jetstream.go","lineNumber":2952,"sourceCode":"\t\t}\n\t}\n\t// If not clustered no checks needed past here.\n\tif !o.JetStream || o.Cluster.Port == 0 {\n\t\treturn nil\n\t}\n\tif o.ServerName == _EMPTY_ {\n\t\treturn fmt.Errorf(\"jetstream cluster requires `server_name` to be set\")\n\t}\n\tif o.Cluster.Name == _EMPTY_ {\n\t\treturn fmt.Errorf(\"jetstream cluster requires `cluster.name` to be set\")\n\t}\n\n\th := strings.ToLower(o.JetStreamExtHint)\n\tswitch h {\n\tcase jsWillExtend, jsNoExtend, _EMPTY_:\n\t\to.JetStreamExtHint = h\n\tdefault:\n\t\treturn fmt.Errorf(\"expected 'no_extend' for string value, got '%s'\", h)\n\t}\n\n\tif o.JetStreamMaxCatchup < 0 {\n\t\treturn fmt.Errorf(\"jetstream max catchup cannot be negative\")\n\t}\n\treturn nil\n}\n\n// We had a bug that set a default de dupe window on mirror, despite that being not a valid config\nfunc fixCfgMirrorWithDedupWindow(cfg *StreamConfig) {\n\tif cfg == nil || cfg.Mirror == nil {\n\t\treturn\n\t}\n\tif cfg.Duplicates != 0 {\n\t\tcfg.Duplicates = 0\n\t}\n}\n","sourceCodeStart":2934,"sourceCodeEnd":2970,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jetstream.go#L2934-L2970","documentation":"The `jetstream.extend_write` (JetStreamExtHint) option accepts only the literal strings 'extend' (jsWillExtend), 'no_extend', or an empty value; anything else after lowercasing is rejected at validation. This hint tells the server how external (non-NATS) writers to mirrored/direct streams should behave.","triggerScenarios":"Setting jetstream extend_write to any string other than \"extend\", \"no_extend\", or \"\" — e.g. a misspelled value, wrong casing handled incorrectly, or a boolean/numeric value serialized as an unexpected string.","commonSituations":"Typo like \"no-extent\" or \"noextend\"; config tooling writing \"true\"/\"false\" into a string-only enum option; upgrading from configs written for a different option shape.","solutions":["Change the value to exactly `no_extend` if you want external writes not to extend, or `extend` if they should.","Remove the option entirely (empty value is allowed) to use the default behavior.","Restart the server to re-validate."],"exampleFix":"// before\njetstream: { extend_write: \"disabled\" }\n// after\njetstream: { extend_write: \"no_extend\" }","handlingStrategy":"validation","validationCode":"v := strings.ToLower(cfg.JetStream.ExtendWrite)\nswitch v {\ncase \"\", \"extend\", \"no_extend\":\n    // ok\ndefault:\n    return fmt.Errorf(\"extend_write must be 'extend' or 'no_extend', got %q\", v)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a string enum/whitelist when generating this option.","Never write booleans or free-form text into extend_write.","Copy option values from official docs, not memory."],"tags":["jetstream","configuration","enum-validation"],"backgroundTag":"invalid-enum-value","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}