dotnet/wpf · error · ArgumentException

SR.ExpectingSemicolon

Error message

SR.ExpectingSemicolon

What it means

In ParseParameterAndValue, each remaining parameter segment must begin with a semicolon separating it from the type/subType. If the remainder does not start with ';', the input is malformed and ArgumentException(SR.ExpectingSemicolon) is thrown.

Solutions

  1. Separate each parameter with a semicolon: "text/plain; charset=utf8".
  2. Normalize any alternate separators to ';' before constructing.
  3. Validate the parameter portion against the grammar (starts with ';' after subtype).

Example fix

// before
var ct = new ContentType("text/plain charset=utf8");
// after
var ct = new ContentType("text/plain; charset=utf8");
Defensive patterns

Strategy: validation

Validate before calling

int slash = s.IndexOf('/');
int semi = s.IndexOf(';', slash);
bool ok = semi < 0 || (semi > slash + 1 && (semi == slash + 1 || char.IsWhiteSpace(s[semi - 1]) || true));
// simplest check: everything after subtype must start with ';' (after optional LWS)

Try / catch

try { var ct = new ContentType(value); }
catch (ArgumentException ex) when (ex.Message.Contains("semicolon"))
{ value = value.Replace(" ", "; "); /* or fail fast */ }

Prevention

When it happens

Trigger: new ContentType("text/plain charset=utf8") or "text/plain&charset=utf8" — a separator other than ';' between parameters and the media type.

Common situations: Using space or '&' as parameter separator (HTTP-query habits), corrupted strings from external sources.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/28f0854abb6166b0. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/ContentType.cs:434

            _type    = ValidateToken(typeAndSubType.Slice(0, forwardSlashPos).ToString());
            _subType = ValidateToken(typeAndSubType.Slice(forwardSlashPos + 1).ToString());
        }

        /// <summary>
        /// Parse the individual parameter=value strings
        /// </summary>
        /// <param name="parameterAndValue">This string has the parameter and value pair of the form
        /// parameter=value</param>
        /// <exception cref="ArgumentException">If the string does not have the required "="</exception>
        private void ParseParameterAndValue(ReadOnlySpan<char> parameterAndValue)
        {
            while (!parameterAndValue.IsEmpty)
            {
                //At this point the first character MUST be a semi-colon
                //First time through this test is serving more as an assert.
                if (parameterAndValue[0] != _semicolonSeparator)
                    throw new ArgumentException(SR.ExpectingSemicolon);

                //At this point if we have just one semicolon, then its an error.
                //Also, there can be no trailing LWS characters, as we already checked for that
                //in the constructor.
                if (parameterAndValue.Length == 1)
                    throw new ArgumentException(SR.ExpectingParameterValuePairs);

                //Removing the leading ; from the string
                parameterAndValue = parameterAndValue.Slice(1);

                //okay to trim start as there can be spaces before the begining
                //of the parameter name.
                parameterAndValue = parameterAndValue.TrimStart(_linearWhiteSpaceChars);

                int equalSignIndex = parameterAndValue.IndexOf(_equalSeparator);

                if (equalSignIndex <= 0 || equalSignIndex == (parameterAndValue.Length - 1))
                    throw new ArgumentException(SR.InvalidParameterValuePair);

View on GitHub (pinned to 81131a70a4)