stride3d/stride · error · YamlException

Unable to decode char from

Error message

Unable to decode char from [{text}]. Expecting a string of length == 1

What it means

PrimitiveSerializer.ConvertFrom throws this when a YAML scalar is being converted to a System.Char but the scalar text does not contain exactly one character. The YamlException includes the scalar's start/end locations. It guards the text.ToCharArray()[0] access which would otherwise fail on empty or multi-character strings.

Solutions

  1. Fix the YAML source so the scalar for the char-typed member is exactly one character.
  2. If the field should hold more text, change the property type from char to string.
  3. Pre-validate the scalar length before conversion and emit a clearer error.
  4. Escape/trim quotes if the value is a single character wrapped in extra quotes.

Example fix

// before (YAML)
delimiter: none
// after
delimiter: ,
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidCharScalar(string text, out char value) { value = default; return text != null && text.Length == 1 && char.TryParse(text, out value); }

Type guard

static bool IsSingleChar(string s) => s != null && s.Length == 1;

Try / catch

try { var c = serializer.Deserialize<char>(reader); } catch (YamlException ex) { throw new FormatException($"Char scalar at {ex.Start} must be exactly one character", ex); }

Prevention

When it happens

Trigger: Deserializing a YAML scalar into a property or field whose type is char (TypeCode.Char) where the scalar value has length 0 or > 1, e.g. 'ab', an empty quoted string "", or a whole word assigned to a char member.

Common situations: Config files where a user writes a word or an empty value for a char-typed field (e.g. delimiter: none); JSON/YAML round-trips that emit multi-character strings into char slots; accidentally quoting a char in YAML so 'a' becomes a two-char string with quotes included.

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 stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/87bb29a2e82cc09d. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Yaml/Serialization/Serializers/PrimitiveSerializer.cs:121

                case TypeCode.String:
                    return text;
            }

            if (type == typeof(TimeSpan))
            {
                return TimeSpan.Parse(text, CultureInfo.InvariantCulture);
            }

            // Remove _ character from numeric values
            text = text.Replace("_", string.Empty);

            // Parse default types 
            switch (Type.GetTypeCode(type))
            {
                case TypeCode.Char:
                    if (text.Length != 1)
                    {
                        throw new YamlException(scalar.Start, scalar.End, $"Unable to decode char from [{text}]. Expecting a string of length == 1");
                    }
                    return text.ToCharArray()[0];
                case TypeCode.Byte:
                    return byte.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.SByte:
                    return sbyte.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.Int16:
                    return short.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.UInt16:
                    return ushort.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.Int32:
                    return int.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.UInt32:
                    return uint.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.Int64:
                    return long.Parse(text, CultureInfo.InvariantCulture);
                case TypeCode.UInt64:
                    return ulong.Parse(text, CultureInfo.InvariantCulture);

View on GitHub (pinned to 96fad776d2)