siyuan-note/siyuan · error

[paths] is required

Error message

[paths] is required

What it means

The asset cloud-upload-by-paths endpoint requires a 'paths' array in the request. blockRequestFields decodes the body into fields, and if 'paths' is absent or the literal JSON null, the decoder returns '[paths] is required'. The request is rejected before any further field decoding.

Solutions

  1. Include 'paths' as a JSON array of asset paths in the request body
  2. Guard client-side: if the paths list is empty, skip the API call instead of sending an empty/absent field
  3. Verify the body is valid JSON (Content-Type: application/json) so the field decoder sees paths

Example fix

// before
fetchPost("/api/asset/uploadCloudByAssetsPaths", {});
// after
fetchPost("/api/asset/uploadCloudByAssetsPaths", {paths: ["assets/foo.png"]});
Defensive patterns

Strategy: validation

Validate before calling

function assertPaths(payload) { if (!Array.isArray(payload.paths) || payload.paths.length === 0) throw new Error("[paths] is required"); }

Type guard

const hasPaths = (p) => p != null && Array.isArray(p.paths) && p.paths.length > 0;

Try / catch

try { await post("/api/asset/uploadCloudByAssetsPaths", payload); } catch (e) { if (/\[paths\] is required/.test(e.message)) { /* abort: nothing to upload */ } else throw e; }

Prevention

When it happens

Trigger: POST /api/asset/uploadCloudByAssetsPaths with body missing 'paths', or {"paths": null}, or not valid JSON containing paths.

Common situations: Scripts that build the payload conditionally and skip paths when a list is empty/unset, older client versions using a different payload shape, copy-pasted curl commands without the field.

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


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

Appendix: source

Thrown at kernel/apicontract/asset.go:158

		fields, err := blockRequestFields(reader, "/api/asset/insertLocalAssets")
		if err != nil {
			return request, err
		}
		fromHTMLPaste := fields["fromHTMLPaste"]
		delete(fields, "fromHTMLPaste")
		if err = decodeRequestFields(reflect.ValueOf(&request).Elem(), fields); err != nil {
			return request, err
		}
		_ = json.Unmarshal(fromHTMLPaste, &request.FromHTMLPaste)
		return request, nil
	}
	AssetUploadCloudByAssetsPaths.decodeRequest = func(reader io.Reader) (request AssetPathsCloudUploadRequest, err error) {
		fields, err := blockRequestFields(reader, "/api/asset/uploadCloudByAssetsPaths")
		if err != nil {
			return request, err
		}
		if len(fields["paths"]) == 0 || string(fields["paths"]) == "null" {
			return request, errors.New("[paths] is required")
		}
		err = decodeRequestFields(reflect.ValueOf(&request).Elem(), fields)
		return request, err
	}
}

View on GitHub (pinned to 9f775e8a12)