{"record":{"id":"ba307ab76a59c675","repo":"elsa-workflows/elsa-core","slug":"failed-to-parse-if-match-header-value","errorCode":null,"errorMessage":"Failed to parse If-Match header value","messagePattern":"Failed to parse If-Match header value","errorType":"http","errorClass":"HttpBadRequestException","httpStatus":400,"severity":"warning","filePath":"src/modules/Elsa.Http/Activities/WriteFileHttpResponse.cs","lineNumber":294,"sourceCode":"            return headers.TryGetValue(HeaderNames.Range, out var header) ? RangeHeaderValue.Parse(header.ToString()) : null;\n            \n        }\n        catch (Exception e)\n        {\n            throw new HttpBadRequestException(\"Failed to parse Range header value\", e);\n        }\n    }\n    \n    private static EntityTagHeaderValue? GetIfMatchHeaderValue(IHeaderDictionary headers)\n    {\n        try\n        {\n            return headers.TryGetValue(HeaderNames.IfMatch, out var header) ? new EntityTagHeaderValue(header.ToString()) : null;\n            \n        }\n        catch (Exception e)\n        {\n            throw new HttpBadRequestException(\"Failed to parse If-Match header value\", e);\n        }\n    }\n}\n\n","sourceCodeStart":276,"sourceCodeEnd":299,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Http/Activities/WriteFileHttpResponse.cs#L276-L299","documentation":"WriteFileHttpResponse validates conditional requests via the If-Match header for optimistic concurrency. GetIfMatchHeaderValue parses the header into an EntityTagHeaderValue; malformed ETags (missing quotes, stray characters) cause the parse to fail and the activity throws HttpBadRequestException with message 'Failed to parse If-Match header value', rejecting the request as a client error.","triggerScenarios":"A client supplies an If-Match header that is not a valid ETag — e.g., 'If-Match: abc123' (unquoted), 'If-Match: W/weak-without-quotes', or containing commas/invalid characters — while WriteFileHttpResponse evaluates preconditions.","commonSituations":"Clients storing the ETag and re-sending it without the surrounding quotes, manually built curl requests omitting quotes around the tag, or intermediary systems corrupting the header value.","solutions":["Send the ETag exactly as received, including quotes and any W/ weak validator prefix, e.g. 'If-Match: \"33a64df551425fcc55e4d42a148795d9f25f89d4\"'.","Omit the If-Match header if conditional validation is not required.","Handle the HttpBadRequestException to return a 400 with guidance on ETag format to API consumers."],"exampleFix":"// before (client request header)\nIf-Match: 33a64df551425fcc55e4d42a148795d9f25f89d4\n// after\nIf-Match: \"33a64df551425fcc55e4d42a148795d9f25f89d4\"","handlingStrategy":"validation","validationCode":"// Client side: ensure the ETag is quoted before sending If-Match\nstring FormatIfMatch(string etag) => etag.StartsWith('\"') ? etag : $\"\\\"{etag.Trim('W', '/')}\\\"\";","typeGuard":null,"tryCatchPattern":"try\n{\n    await workflowRunner.RunAsync(workflow, request);\n}\ncatch (HttpBadRequestException ex) when (ex.Message.Contains(\"If-Match\"))\n{\n    httpContext.Response.StatusCode = 400;\n    await httpContext.Response.WriteAsJsonAsync(new { error = \"If-Match must be a quoted ETag\" });\n}","preventionTips":["Always store and re-send ETags verbatim, including quotes and W/ prefix.","Avoid constructing If-Match headers by string concatenation without quoting.","Only send If-Match when optimistic concurrency is actually needed."],"tags":["http","etag","bad-request","headers"],"backgroundTag":"invalid-argument-format","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}