{"record":{"id":"091286f4453b59df","repo":"dotnet/yarp","slug":"routevaluekey-cannot-be-null-or-empty","errorCode":null,"errorMessage":"'routeValueKey' cannot be null or empty.","messagePattern":"'routeValueKey' cannot be null or empty\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Transforms/RequestHeaderRouteValueTransform.cs","lineNumber":20,"sourceCode":"// The .NET Foundation licenses this file to you under the MIT license.\n\nusing System;\n\nnamespace Yarp.ReverseProxy.Transforms;\n\npublic class RequestHeaderRouteValueTransform : RequestHeaderTransform\n{\n    public RequestHeaderRouteValueTransform(string headerName, string routeValueKey, bool append)\n        : base(headerName, append)\n    {\n        if (string.IsNullOrEmpty(headerName))\n        {\n            throw new ArgumentException($\"'{nameof(headerName)}' cannot be null or empty.\", nameof(headerName));\n        }\n\n        if (string.IsNullOrEmpty(routeValueKey))\n        {\n            throw new ArgumentException($\"'{nameof(routeValueKey)}' cannot be null or empty.\", nameof(routeValueKey));\n        }\n\n        RouteValueKey = routeValueKey;\n    }\n\n    internal string RouteValueKey { get; }\n\n    protected override string? GetValue(RequestTransformContext context)\n    {\n        var routeValues = context.HttpContext.Request.RouteValues;\n        if (!routeValues.TryGetValue(RouteValueKey, out var value))\n        {\n            return null;\n        }\n\n        return value?.ToString();\n    }\n}","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Transforms/RequestHeaderRouteValueTransform.cs#L2-L38","documentation":"The second guard in RequestHeaderRouteValueTransform's constructor: after headerName passes, routeValueKey is checked and must be non-null/non-empty. The transform reads a value from HttpContext.Request.RouteValues by this key, so an empty key cannot locate anything.","triggerScenarios":"Constructing `new RequestHeaderRouteValueTransform(headerName, routeValueKey, append)` where routeValueKey is null or empty. Via config this is the value of the 'Set'/'Append' sibling under a 'RequestHeaderRouteValue' transform.","commonSituations":"Config `{ \"RequestHeaderRouteValue\": \"X-Hdr\", \"Set\": \"\" }`; a programmatic call where the route-value key variable was never assigned; mismatched route parameter name.","solutions":["Supply a route-value key that exists in your route template, e.g. \"userId\".","Make sure the 'Set'/'Append' value in config is non-empty.","Confirm the key matches a {param} in the route pattern so the transform resolves a value."],"exampleFix":"// before\n{ \"RequestHeaderRouteValue\": \"X-User\", \"Set\": \"\" }\n// after\n{ \"RequestHeaderRouteValue\": \"X-User\", \"Set\": \"userId\" }","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(routeValueKey))\n    throw new InvalidOperationException(\"routeValueKey must reference a route parameter.\");\nvar t = new RequestHeaderRouteValueTransform(headerName, routeValueKey, append);","typeGuard":"static bool IsValidRouteKey(string? key)\n    => !string.IsNullOrWhiteSpace(key);","tryCatchPattern":null,"preventionTips":["Make sure the route-value key corresponds to a {param} in the route pattern.","Validate non-empty config values for the Set/Append sibling of RequestHeaderRouteValue.","Log the resolved routeValueKey during development to catch empty values early."],"tags":["yarp","transforms","argument-validation","headers","routing"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}