{"record":{"id":"5672270cd24f65b7","repo":"dotnet/yarp","slug":"unexpected-parameters-for-responsetrailer-string","errorCode":null,"errorMessage":"Unexpected parameters for ResponseTrailer: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'","messagePattern":"Unexpected parameters for ResponseTrailer: (.+?)\\. Expected 'Set' or 'Append'","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Transforms/ResponseTransformFactory.cs","lineNumber":189,"sourceCode":"                TransformHelpers.CheckTooManyParameters(transformValues, expected: 3);\n                condition = Enum.Parse<ResponseCondition>(whenValue, ignoreCase: true);\n            }\n            else\n            {\n                TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);\n            }\n\n            if (transformValues.TryGetValue(SetKey, out var setValue))\n            {\n                context.AddResponseTrailer(responseTrailerName, setValue, append: false, condition);\n            }\n            else if (transformValues.TryGetValue(AppendKey, out var appendValue))\n            {\n                context.AddResponseTrailer(responseTrailerName, appendValue, append: true, condition);\n            }\n            else\n            {\n                throw new ArgumentException($\"Unexpected parameters for ResponseTrailer: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'\");\n            }\n        }\n        else if (transformValues.TryGetValue(ResponseHeaderRemoveKey, out var removeResponseHeaderName))\n        {\n            var condition = ResponseCondition.Success;\n            if (transformValues.TryGetValue(WhenKey, out var whenValue))\n            {\n                TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);\n                condition = Enum.Parse<ResponseCondition>(whenValue, ignoreCase: true);\n            }\n            else\n            {\n                TransformHelpers.CheckTooManyParameters(transformValues, expected: 1);\n            }\n\n            context.AddResponseHeaderRemove(removeResponseHeaderName, condition);\n        }\n        else if (transformValues.TryGetValue(ResponseTrailerRemoveKey, out var removeResponseTrailerName))","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Transforms/ResponseTransformFactory.cs#L171-L207","documentation":"Thrown by ResponseTransformFactory.Build when a 'ResponseTrailer' transform key is present but neither 'Set' nor 'Append' is among the sibling keys. Uses ArgumentException with a descriptive message listing the keys found. An optional 'When' key may also be present. Validate catches the same condition non-throwing during config loading.","triggerScenarios":"A transform dictionary like { \"ResponseTrailer\": \"X-Grpc\" } with no Set/Append. Reaches Build when config validation is bypassed or transforms are constructed programmatically.","commonSituations":"appsettings.json transform missing Set/Append; typo'd sibling key; a config-database-driven route store emitting an incomplete trailer transform.","solutions":["Add 'Set' or 'Append' to the entry, e.g. { \"ResponseTrailer\": \"X-Grpc\", \"Set\": \"v\" }.","Correct key-name typos (case-sensitive).","Ensure config validation runs at startup.","Validate the dictionary keys in code before calling Build."],"exampleFix":"// before\n{ \"ResponseTrailer\": \"X-Grpc\" }\n// after\n{ \"ResponseTrailer\": \"X-Grpc\", \"Set\": \"ok\", \"When\": \"Success\" }","handlingStrategy":"validation","validationCode":"if (transformValues.ContainsKey(\"ResponseTrailer\")\n    && !transformValues.ContainsKey(\"Set\")\n    && !transformValues.ContainsKey(\"Append\"))\n{\n    throw new InvalidOperationException(\n        \"ResponseTrailer transform requires 'Set' or 'Append'.\");\n}","typeGuard":"static bool IsValidResponseTrailerTransform(IReadOnlyDictionary<string, string> t)\n    => t.ContainsKey(\"ResponseTrailer\")\n       && (t.ContainsKey(\"Set\") || t.ContainsKey(\"Append\"));","tryCatchPattern":null,"preventionTips":["Keep YARP startup config validation enabled.","Validate transform dictionaries in code before calling Build.","Ensure dynamically generated trailer transforms include Set or Append."],"tags":["yarp","config","transforms","trailers","response"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}