{"record":{"id":"3897db656112d3e6","repo":"dotnet/yarp","slug":"headername-cannot-be-null-or-empty-3897db","errorCode":null,"errorMessage":"'headerName' cannot be null or empty.","messagePattern":"'headerName' cannot be null or empty\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Transforms/RequestHeaderRouteValueTransform.cs","lineNumber":15,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// 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;","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Transforms/RequestHeaderRouteValueTransform.cs#L1-L33","documentation":"RequestHeaderRouteValueTransform's constructor validates that headerName is non-null/non-empty (the first guard, before checking routeValueKey). Because the transform sets a request header from a route value, both names are mandatory. A null/empty header name is a programming error that cannot produce a functioning transform.","triggerScenarios":"Calling `new RequestHeaderRouteValueTransform(headerName, routeValueKey, append)` where headerName is null or empty. Also reached via context.AddRequestHeaderRouteValue when the 'RequestHeaderRouteValue' config key resolves to an empty string.","commonSituations":"Config entry `{ \"RequestHeaderRouteValue\": \"\", \"Set\": \"x\" }`; a programmatic transform with an empty header name variable; refactoring that cleared the header name.","solutions":["Provide a non-empty header name, e.g. \"X-Route-Id\".","Ensure the RequestHeaderRouteValue config value is populated.","Validate headerName at the call site before constructing."],"exampleFix":"// before\nnew RequestHeaderRouteValueTransform(\"\", routeValueKey, append);\n// after\nnew RequestHeaderRouteValueTransform(\"X-Route-Id\", routeValueKey, append);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(headerName))\n    throw new InvalidOperationException(\"headerName is required.\");\nif (string.IsNullOrEmpty(routeValueKey))\n    throw new InvalidOperationException(\"routeValueKey is required.\");\nvar t = new RequestHeaderRouteValueTransform(headerName, routeValueKey, append);","typeGuard":"static bool IsValidHeaderAndRouteKey(string? header, string? route)\n    => !string.IsNullOrWhiteSpace(header) && !string.IsNullOrWhiteSpace(route);","tryCatchPattern":null,"preventionTips":["Confirm both the header name and route-value key are non-empty before constructing.","Ensure the route-value key matches a parameter in the route template.","Validate config entries for RequestHeaderRouteValue transforms at startup."],"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"}