siyuan-note/siyuan · error

Field [values]: should be of type [Object]

Error message

Field [values]: should be of type [Object]

What it means

This error is returned when decoding the request body for POST /api/storage/setViewState (the PatchViewState endpoint). The generic decoder detects that the `values` field failed to unmarshal into map[string]JSONValue, and this wrapper rewrites the message into a friendlier form. It means the JSON you sent has `values` as a non-object (e.g. a string, array, number, or boolean) instead of a JSON object of key/value pairs.

Solutions

  1. Send `values` as a JSON object: {"key":"<stateKey>","values":{"someKey":123}}
  2. If you only want to delete entries, omit `values` (it is optional) and pass `removeKeys` as an array of non-empty strings
  3. Validate the payload with JSON.parse/typeof checks before the HTTP call

Example fix

// before
{"key":"local", "values":"{\"width\":300}"}
// after
{"key":"local", "values":{"width":300}}
Defensive patterns

Strategy: validation

Validate before calling

function isViewStatePatchPayload(p){ return p && typeof p.key === 'string' && (p.values === undefined || (typeof p.values === 'object' && p.values !== null && !Array.isArray(p.values))); }

Type guard

const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);

Try / catch

try { const res = await fetchPost('/api/storage/setViewState', payload); if (res.code !== 0) console.error(res.msg); } catch (e) { /* network failure */ }

Prevention

When it happens

Trigger: Calling /api/storage/setViewState with `values` set to a scalar or array, e.g. {"key":"local","values":"oops"} or {"key":"local","values":[1,2]}; also when `values` has a wrong nested type the decoder reports a Field [values] prefix error which is rewritten here.

Common situations: Manually hand-crafting the curl payload for view-state persistence; an old client version sending the pre-patch flat format; a script serializing values with JSON.stringify applied twice so `values` becomes a string.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/2d752817f04f3e9b. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/storage.go:39

		var entries []json.RawMessage
		if json.Unmarshal(raw, &entries) != nil {
			return request, errors.New("Field [rootIDs] should be of type [Array]")
		}
		for _, entry := range entries {
			var id string
			if json.Unmarshal(entry, &id) == nil && id != "" {
				request.RootIDs = append(request.RootIDs, id)
			}
		}
		return
	}
	plain := PatchViewState
	PatchViewState.decodeRequest = func(reader io.Reader) (ViewStatePatchRequest, error) {
		request, err := plain.Decode(reader)
		if err != nil {
			switch {
			case strings.HasPrefix(err.Error(), "Field [values]"):
				err = errors.New("Field [values]: should be of type [Object]")
			case strings.HasPrefix(err.Error(), "Field [removeKeys]"):
				err = errors.New("Field [removeKeys]: each element should be a non-empty String")
			}
		}
		return request, err
	}
}

type RecentDocUpdateRequest struct {
	RootID string `json:"rootID" api:"optional,nullable"`
}
type RecentDocsUpdateRequest struct {
	RootIDs []string `json:"rootIDs" api:"optional,nullable"`
}

type StorageKeyRequest struct {
	Key string `json:"key" api:"trim"`
}

View on GitHub (pinned to 9f775e8a12)