{"record":{"id":"b9228811dd3ee495","repo":"dotnet/yarp","slug":"headername-cannot-be-null-or-empty-b92288","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/ResponseTrailerValueTransform.cs","lineNumber":19,"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;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Primitives;\n\nnamespace Yarp.ReverseProxy.Transforms;\n\n/// <summary>\n/// Sets or appends simple response trailer values.\n/// </summary>\npublic class ResponseTrailerValueTransform : ResponseTrailersTransform\n{\n    public ResponseTrailerValueTransform(string headerName, string value, bool append, ResponseCondition condition)\n    {\n        if (string.IsNullOrEmpty(headerName))\n        {\n            throw new ArgumentException($\"'{nameof(headerName)}' cannot be null or empty.\", nameof(headerName));\n        }\n\n        HeaderName = headerName;\n        ArgumentNullException.ThrowIfNull(value);\n        Value = value;\n        Append = append;\n        Condition = condition;\n    }\n\n    internal ResponseCondition Condition { get; }\n\n    internal bool Append { get; }\n\n    internal string HeaderName { get; }\n\n    internal string Value { get; }\n\n    // Assumes the response status code has been set on the HttpContext already.","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Transforms/ResponseTrailerValueTransform.cs#L1-L37","documentation":"ResponseTrailerValueTransform's constructor validates headerName (non-null/non-empty) and value (non-null). The transform sets or appends a response trailer value, so both the name and value must be concrete. A ResponseCondition controls when it applies.","triggerScenarios":"Constructing `new ResponseTrailerValueTransform(headerName, value, append, condition)` where headerName is null or empty. Via config this is the 'ResponseTrailer' key value.","commonSituations":"Config `{ \"ResponseTrailer\": \"\", \"Set\": \"x\" }`; a programmatic transform with an empty name; refactoring that dropped the name.","solutions":["Pass a non-empty trailer name such as \"X-Grpc-Status\".","Ensure the config ResponseTrailer value is populated.","Validate headerName at the call site before constructing."],"exampleFix":"// before\nnew ResponseTrailerValueTransform(\"\", \"v\", true, ResponseCondition.Success);\n// after\nnew ResponseTrailerValueTransform(\"X-Grpc-Status\", \"v\", true, ResponseCondition.Success);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(headerName))\n    throw new InvalidOperationException(\"Trailer name is required.\");\nif (value is null)\n    throw new InvalidOperationException(\"Trailer value is required.\");\nvar t = new ResponseTrailerValueTransform(headerName, value, append, condition);","typeGuard":"static bool IsValidHeaderAndValue(string? name, string? value)\n    => !string.IsNullOrWhiteSpace(name) && value is not null;","tryCatchPattern":null,"preventionTips":["Validate both trailer name and value before constructing.","Ensure config ResponseTrailer/Set values are populated.","Use context.AddResponseTrailer from validated config."],"tags":["yarp","transforms","argument-validation","trailers","response"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}