d2lang/d2 · error
failed to unmarshal Range from %q: missing Start field
Error message
failed to unmarshal Range from %q: missing Start field
What it means
After extracting the End field via the last '-', UnmarshalText looks for a ',' separating the path from the Start position. This error means no ',' was found, so the Start field is missing. The wrapping message 'failed to unmarshal Range from %q' includes the offending input.
Source
Thrown at d2ast/d2ast.go:143
start, _ := r.Start.MarshalText()
end, _ := r.End.MarshalText()
return []byte(fmt.Sprintf("%s,%s-%s", r.Path, start, end)), nil
}
// See docs on Range.
func (r *Range) UnmarshalText(b []byte) (err error) {
defer xdefer.Errorf(&err, "failed to unmarshal Range from %q", b)
i := bytes.LastIndexByte(b, '-')
if i == -1 {
return errors.New("missing End field")
}
end := b[i+1:]
b = b[:i]
i = bytes.LastIndexByte(b, ',')
if i == -1 {
return errors.New("missing Start field")
}
start := b[i+1:]
b = b[:i]
r.Path = string(b)
err = r.Start.UnmarshalText(start)
if err != nil {
return err
}
return r.End.UnmarshalText(end)
}
func (r Range) Before(r2 Range) bool {
return r.Start.Before(r2.Start)
}
// Position represents a line:column and byte position in a file.
//View on GitHub (pinned to 0d69dca6f5)
Solutions
- Format the input as "path,start-end", e.g. "file.d2,1:0:0-1:5:5".
- Ensure the path segment followed by ',' is present before the start position.
- Round-trip through MarshalText to get a canonical string instead of hand-building one.
Example fix
// before
r.UnmarshalText("1:0:0-1:5:5")
// after
r.UnmarshalText("file.d2,1:0:0-1:5:5") Defensive patterns
Strategy: validation
Validate before calling
func hasStartField(s string) bool { i := strings.LastIndexByte(s, '-'); return i > 0 && strings.Contains(s[:i], ",") }
if !hasStartField(input) { return errors.New("range text needs a comma before the start position") } Type guard
func isFullRangeText(s string) bool { parts := strings.SplitN(s, "-", 2); return len(parts) == 2 && strings.Contains(parts[0], ",") } Try / catch
var r d2ast.Range
if err := r.UnmarshalText(input); err != nil {
return fmt.Errorf("range %q missing start/path: %w", input, err)
} Prevention
- Include the path segment plus ',' before the start position.
- Round-trip through MarshalText to canonicalize.
- Validate with a quick comma check before calling UnmarshalText.
When it happens
Trigger: Calling Range.UnmarshalText/MakeRange with a string that has a '-' but no ',' (e.g. "1:0-1:5" without the path part, or "file.d2 1:0-1:5").
Common situations: Passing a bare position-pair string instead of the full "path,start-end" format, or dropping the path and its comma when transforming serialized values.
Related errors
- failed to unmarshal Range from %q: missing End field
- failed to unmarshal Position from %q: expected three fields
- invalid gradient syntax
- no parameters in gradient
- no color stops in gradient
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/9f568bcb3d743762.
Report an issue: GitHub.