{"record":{"id":"021e0affa301676c","repo":"dotnet/yarp","slug":"a-non-empty-customtransform-value-is-required","errorCode":null,"errorMessage":"A non-empty CustomTransform value is required","messagePattern":"A non-empty CustomTransform value is required","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"samples/ReverseProxy.Transforms.Sample/MyTransformFactory.cs","lineNumber":34,"sourceCode":"            if (transformValues.TryGetValue(\"CustomTransform\", out var value))\n            {\n                if (string.IsNullOrEmpty(value))\n                {\n                    context.Errors.Add(new ArgumentException(\"A non-empty CustomTransform value is required\"));\n                }\n\n                return true; // Matched\n            }\n            return false;\n        }\n\n        public bool Build(TransformBuilderContext context, IReadOnlyDictionary<string, string> transformValues)\n        {\n            if (transformValues.TryGetValue(\"CustomTransform\", out var value))\n            {\n                if (string.IsNullOrEmpty(value))\n                {\n                    throw new ArgumentException(\"A non-empty CustomTransform value is required\");\n                }\n\n                context.AddRequestTransform(transformContext =>\n                {\n                    transformContext.ProxyRequest.Options.Set(new HttpRequestOptionsKey<string>(\"CustomTransform\"), value);\n                    return default;\n                });\n\n                return true;\n            }\n\n            return false;\n        }\n    }\n}\n","sourceCodeStart":16,"sourceCodeEnd":50,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/samples/ReverseProxy.Transforms.Sample/MyTransformFactory.cs#L16-L50","documentation":"Thrown by the MyTransformFactory sample (ITransformFactory.Build) when a transform dictionary contains the key \"CustomTransform\" but its value is null or empty. This sample transform attaches the value as an HttpRequestOptionsKey on proxied requests and requires a non-empty payload. It is illustrative sample code showing how to enforce transform-value validation at build time.","triggerScenarios":"A route's Transforms collection includes an entry like { \"CustomTransform\": \"\" } or { \"CustomTransform\": null } in appsettings.json or programmatic config. Build is invoked during proxy pipeline construction when the route is activated.","commonSituations":"Configuring a transform block with an empty value by mistake. Copy-pasting a transform template and forgetting to fill in the value. YAML/JSON key present but value omitted.","solutions":["Provide a non-empty value for the CustomTransform key in the route's Transforms config.","Remove the CustomTransform entry entirely if the transform is not needed for that route.","Register the MyTransformFactory with AddTransforms<MyTransformFactory>() so the sample recognizes the key."],"exampleFix":"// before — appsettings.json\n\"Transforms\": [ { \"CustomTransform\": \"\" } ]\n// after\n\"Transforms\": [ { \"CustomTransform\": \"my-value\" } ]","handlingStrategy":"validation","validationCode":"if (transformValues.TryGetValue(\"CustomTransform\", out var v) && string.IsNullOrEmpty(v))\n{\n    // surface a config validation error at startup instead of letting Build throw\n    context.Errors.Add(new ArgumentException(\"A non-empty CustomTransform value is required\"));\n}","typeGuard":"static bool IsValidCustomTransformValue(string? v) => !string.IsNullOrWhiteSpace(v);","tryCatchPattern":"try { factory.Build(context, transformValues); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"CustomTransform\"))\n{ logger.LogWarning(ex, \"Skipping transform due to empty value\"); }","preventionTips":["Enable YARP config validation (default on) so Validate() reports empty transform values at startup.","Unit-test transform config JSON against the factory's Validate before deploy.","Treat transform config as code: review in PRs."],"tags":["transforms","configuration","validation","sample"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}