siyuan-note/siyuan · error
right document version is required
Error message
right document version is required
What it means
Symmetric to the left-side check, the diffDocVersions decoder requires a `right` field holding a document version reference object. Unmarshal failure or a nil result (absent, null, or non-object value) produces 'right document version is required'.
Solutions
- Send "right" as a version reference object alongside left
- Resolve the second history version before invoking the diff endpoint
- Verify the payload with both keys: {"left": {...}, "right": {...}}
Example fix
// before
{"left": {"type": "id", "id": "20240101110000-abcdef0"}}
// after
{"left": {"type": "id", "id": "20240101110000-abcdef0"}, "right": {"type": "id", "id": "20240101120000-abcdef1"}} Defensive patterns
Strategy: validation
Validate before calling
if (!isValidVersionRef(body.right)) throw new Error("right version ref required"); Type guard
const isVersionRef = (v) => v !== null && typeof v === "object" && typeof v.type === "string";
Prevention
- Validate both left and right together in one guard before the API call
- Handle single-selection UI state by disabling the compare action
When it happens
Trigger: POSTing to /api/history/diffDocVersions with only `left` set, "right": null, or right as a non-object value.
Common situations: Selecting 'compare with previous' where the right version failed to resolve and the client sent null; partial request construction.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- left document version is required
- Field [conf] is required
- Field [id] should be of type [String]
- Field [notebook] is required
- Field [ ] is required
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/c7f3fa6e85fe6f75.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/history_diff.go:55
Differences []*DocVersionDifference `json:"differences"`
Large bool `json:"large"`
Fallback bool `json:"fallback"`
Message string `json:"message"`
TitleModified bool `json:"titleModified"`
}
func init() {
DiffDocVersions.decodeRequest = func(reader io.Reader) (request DiffDocVersionsRequest, err error) {
fields, err := blockRequestFields(reader, "/api/history/diffDocVersions")
if err != nil {
return request, err
}
var left, right map[string]json.RawMessage
if json.Unmarshal(fields["left"], &left) != nil || left == nil {
return request, fmt.Errorf("left document version is required")
}
if json.Unmarshal(fields["right"], &right) != nil || right == nil {
return request, fmt.Errorf("right document version is required")
}
if request.Left, err = decodeDocVersionRef(left); err != nil {
return request, err
}
request.Right, err = decodeDocVersionRef(right)
return request, err
}
}
func decodeDocVersionRef(fields map[string]json.RawMessage) (request DocVersionRef, err error) {
if request.Type, err = legacyField[string](fields, "type", "String", true); err != nil {
return request, err
}
request.Type = strings.TrimSpace(request.Type)
if request.Type == "" {
return request, fmt.Errorf("Field [type] must not be empty")
}
if request.ID, err = legacyField[string](fields, "id", "String", false); err != nil {View on GitHub (pinned to 9f775e8a12)