siyuan-note/siyuan · error

invalid JSON: %s

Error message

invalid JSON: %s

What it means

After the four required flags pass, `database update` unmarshals the --value string into a `map[string]any` with encoding/json. If the payload is not syntactically valid JSON, or is valid JSON but not a JSON object (e.g. an array, bare string, or number), json.Unmarshal returns a SyntaxError or UnmarshalTypeError which is wrapped and returned. The error message embeds the underlying json error verbatim, which usually pinpoints the offending byte offset.

Source

Thrown at kernel/cli/cmd/database.go:322

		fmt.Println("ok")
		return nil
	},
}

var databaseItemUpdateCmd = &cobra.Command{
	Use:   "update --av <avID> --key <keyID> --item <itemID> --value <json>",
	Short: "Update a cell value",
	RunE: func(cmd *cobra.Command, args []string) error {
		avID, _ := cmd.Flags().GetString("av")
		keyID, _ := cmd.Flags().GetString("key")
		itemID, _ := cmd.Flags().GetString("item")
		valueStr, _ := cmd.Flags().GetString("value")
		if avID == "" || keyID == "" || itemID == "" || valueStr == "" {
			return fmt.Errorf("--av, --key, --item and --value are required")
		}
		var valueData map[string]any
		if err := json.Unmarshal([]byte(valueStr), &valueData); err != nil {
			return fmt.Errorf("invalid JSON: %s", err)
		}

		if dryRun {
			fmt.Printf("[dry-run] Would update cell in database %s: key=%s item=%s\n", avID, keyID, itemID)
			return nil
		}

		if _, err := model.UpdateAttributeViewCell(nil, avID, keyID, itemID, valueData); err != nil {
			return err
		}
		model.AppendPushReloadAttrViewEntry(avID)
		fmt.Println("ok")
		return nil
	},
}

func printUnusedItems(items []*model.UnusedItem) {
	if len(items) == 0 {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Validate the JSON locally first: `echo '<json>' | jq .` — jq exits non-zero on malformed JSON and reports the position.
  2. Single-quote the whole payload in the shell so inner double quotes survive: `--value '{"col":"v"}'`.
  3. Ensure the top-level JSON value is an object `{}`, not an array or scalar, because the target type is map[string]any.
  4. If building JSON programmatically, use jq -c or a JSON serializer rather than string concatenation; load file contents via `--value "$(cat payload.json)"`.
  5. Read the offset in the embedded json error (e.g. `invalid character 'x' looking for beginning of value`) and fix that exact byte.

Example fix

// before
siyuan database update --av a --key k --item i --value {text: hello}
// after
siyuan database update --av a --key k --item i --value '{"text":"hello"}'
Defensive patterns

Strategy: validation

Validate before calling

# validate JSON and that it is an object before invoking
printf '%s' "$VALUE" | jq -e . >/dev/null && [ "$(printf '%s' "$VALUE" | jq -r 'type')" = 'object' ] || { echo '--value must be a JSON object' >&2; exit 2; }
siyuan database update --av "$AV" --key "$KEY" --item "$ITEM" --value "$VALUE"

Type guard

// Go: ensure the string parses to a JSON object before unmarshalling
func isJSONObject(s string) bool {
	var m map[string]any
	return json.Unmarshal([]byte(s), &m) == nil
}

Try / catch

# show the embedded json error offset to the user
if ! siyuan database update --av "$AV" --key "$KEY" --item "$ITEM" --value "$VALUE" 2>err.txt; then
  grep -q 'invalid JSON' err.txt && echo "fix JSON payload (run: echo \"$VALUE\" | jq .)" >&2
  exit 1
fi

Prevention

When it happens

Trigger: Passing --value with unbalanced braces/quotes; passing a JSON array `[1,2]` or a bare scalar `"hello"` or `42`; passing a shell-quoted string whose inner quotes were stripped by the shell; passing JSON with trailing commas or single quotes; passing the path to a JSON file instead of its contents.

Common situations: Forgetting to single-quote the JSON in the shell so double quotes get consumed; building the JSON with naive string concatenation that produces `{'text': 'x'}` (single quotes are invalid JSON); piping a file path instead of `$(cat file.json)`; locale/encoding issues injecting smart quotes; assuming the value accepts a raw string instead of an object.

Understand the failure class

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/8057c5ee03b8b3b0. Report an issue: GitHub.