{"record":{"id":"494bc1ea9d4bfa07","repo":"nats-io/nats-server","slug":"10145","errorCode":"10145","errorMessage":"%w %s","messagePattern":"%w %s","errorType":"validation","errorClass":"ApiError (JSSourceInvalidSubjectFilter)","httpStatus":400,"severity":"error","filePath":"server/stream.go","lineNumber":2219,"sourceCode":"\tvar iNames = make(map[string]struct{})\n\tvar cNames = make(map[string]struct{})\n\tfor _, src := range cfg.Sources {\n\t\tif src == nil || !isValidAssetName(src.Name) {\n\t\t\treturn StreamConfig{}, NewJSSourceInvalidStreamNameError()\n\t\t}\n\t\tif _, ok := iNames[src.composeIName()]; !ok {\n\t\t\tiNames[src.composeIName()] = struct{}{}\n\t\t} else {\n\t\t\treturn StreamConfig{}, NewJSSourceDuplicateDetectedError()\n\t\t}\n\n\t\tif src.FilterSubject != _EMPTY_ && len(src.SubjectTransforms) != 0 {\n\t\t\treturn StreamConfig{}, NewJSSourceMultipleFiltersNotAllowedError()\n\t\t}\n\n\t\tfor _, tr := range src.SubjectTransforms {\n\t\t\tif tr.Source != _EMPTY_ && !IsValidSubject(tr.Source) {\n\t\t\t\treturn StreamConfig{}, NewJSSourceInvalidSubjectFilterError(fmt.Errorf(\"%w %s\", ErrBadSubject, tr.Source))\n\t\t\t}\n\t\t\terr := ValidateMapping(tr.Source, tr.Destination)\n\t\t\tif err != nil {\n\t\t\t\treturn StreamConfig{}, NewJSSourceInvalidTransformDestinationError(err)\n\t\t\t}\n\t\t}\n\n\t\t// Check subject filters overlap.\n\t\tfor outer, tr := range src.SubjectTransforms {\n\t\t\tfor inner, innertr := range src.SubjectTransforms {\n\t\t\t\tif inner != outer && subjectIsSubsetMatch(tr.Source, innertr.Source) {\n\t\t\t\t\treturn StreamConfig{}, NewJSSourceOverlappingSubjectFiltersError()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif c := src.Consumer; c != nil {\n\t\t\tif !isValidAssetName(c.Name) {","sourceCodeStart":2201,"sourceCodeEnd":2237,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/stream.go#L2201-L2237","documentation":"A stream source's SubjectTransforms entry has an invalid source subject or an invalid source/destination mapping. The server wraps ErrBadSubject with the offending subject (JSSourceInvalidSubjectFilterError, 10151) or fails ValidateMapping (JSSourceInvalidTransformDestinationError) during StreamSource validation.","triggerScenarios":"AddStream/UpdateStream with Sources[].SubjectTransforms where tr.Source is non-empty and !IsValidSubject(tr.Source), or ValidateMapping(tr.Source, tr.Destination) returns an error (e.g. destination that doesn't preserve wildcard token counts).","commonSituations":"Typo'd subjects like 'foo..bar'; transforms mapping 3-token sources to 2-token destinations; programmatic generation of transforms with empty or malformed source strings.","solutions":["Correct the transform Source to a valid NATS subject","Ensure Destination matches the source's token/wildcard structure per ValidateMapping rules","Pre-validate subjects/mappings before submitting the config"],"exampleFix":"// before\ntr := SubjectTransformConfig{Source: \"a.>.b.>\", Destination: \"x\"}\n// after\ntr := SubjectTransformConfig{Source: \"a.b.c\", Destination: \"x.y.c\"}","handlingStrategy":"validation","validationCode":"for _, src := range cfg.Sources {\n    for _, tr := range src.SubjectTransforms {\n        if tr.Source != \"\" && !subjectIsValid(tr.Source) {\n            return fmt.Errorf(\"invalid source transform subject: %q\", tr.Source)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"var ec *jsapi.APIError\nif errors.As(err, &ec) && ec.ErrorCode == 10145 {\n    // locate offending transform in cfg.Sources and fix\n}","preventionTips":["Reuse the same subject-validation helper for mirrors and sources","Guard against empty-token subjects when interpolating values","Test transforms with wildcard sources explicitly"],"tags":["jetstream","stream-source","subject-transform","invalid-subject"],"backgroundTag":"invalid-subject","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}