{"record":{"id":"e12c575698556160","repo":"nats-io/nats-server","slug":"failed-to-create-mapping-transform-for-service-imp","errorCode":null,"errorMessage":"failed to create mapping transform for service import subject from %q to %q: %v","messagePattern":"failed to create mapping transform for service import subject from %q to %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/accounts.go","lineNumber":2190,"sourceCode":"\t\tto = from\n\t}\n\t// Check to see if we have a wildcard\n\tvar (\n\t\tusePub bool\n\t\ttr     *subjectTransform\n\t\terr    error\n\t)\n\n\tif subjectHasWildcard(to) {\n\t\t// If to and from match, then we use the published subject.\n\t\tif to == from {\n\t\t\tusePub = true\n\t\t} else {\n\t\t\tto, _ = transformUntokenize(to)\n\t\t\t// Create a transform. Do so in reverse such that $ symbols only exist in to\n\t\t\tif tr, err = NewSubjectTransformStrict(to, transformTokenize(from)); err != nil {\n\t\t\t\ta.mu.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"failed to create mapping transform for service import subject from %q to %q: %v\",\n\t\t\t\t\tfrom, to, err)\n\t\t\t} else {\n\t\t\t\t// un-tokenize and reverse transform so we get the transform needed\n\t\t\t\tfrom, _ = transformUntokenize(from)\n\t\t\t\ttr = tr.reverse()\n\t\t\t}\n\t\t}\n\t}\n\tvar share bool\n\tif claim != nil {\n\t\tshare = claim.Share\n\t}\n\tsi := &serviceImport{dest, claim, se, nil, from, to, tr, 0, rt, lat, nil, nil, nil, usePub, false, false, share, false, false, atrc, nil}\n\tsis := a.imports.services[from]\n\tsis = append(sis, si)\n\ta.imports.services[from] = sis\n\ta.mu.Unlock()\n","sourceCodeStart":2172,"sourceCodeEnd":2208,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/accounts.go#L2172-L2208","documentation":"AddServiceImport failed to build the subject transform mapping the exported subject back to the local one (server/accounts.go:2190). The server creates a strict reverse transform between 'to' and 'from'; invalid or incompatible token patterns in either subject make NewSubjectTransformStrict fail.","triggerScenarios":"Calling AddServiceImport with 'from'/'to' subjects whose wildcard/token structure cannot be transformed (e.g. mismatched wildcard counts, illegal $ placeholders, invalid tokens after untokenizing).","commonSituations":"Using $-token placeholders inconsistently between from and to; wildcards in 'to' not present in 'from'; subjects with invalid characters.","solutions":["Ensure 'to' and 'from' have compatible token counts and wildcard placement.","If using $ tokens in 'to', mirror the same tokenization in 'from'.","Simplify subjects to plain literals/wildcards if transforms are not needed.","Inspect the wrapped inner error (%v) for the exact transform failure reason."],"exampleFix":"// before\nacc.AddServiceImport(dest, \"req.*\", \"help.a.b.c\") // incompatible token counts\n// after\nacc.AddServiceImport(dest, \"req.*\", \"help.*\")","handlingStrategy":"validation","validationCode":"if _, err := NewSubjectTransformStrict(to, from); err != nil {\n    return fmt.Errorf(\"invalid from/to pair: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := acc.AddServiceImport(dest, from, to); err != nil {\n    if strings.Contains(err.Error(), \"failed to create mapping transform\") {\n        // fix token structure of from/to\n    }\n}","preventionTips":["Keep token counts equal between from and to","Mirror $ placeholders on both sides","Prefer simple subjects when transforms are unnecessary"],"tags":["nats-server","subject-transform","service-import"],"backgroundTag":"invalid-subject-transform","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}