{"record":{"id":"a5f3111c86f959bc","repo":"siyuan-note/siyuan","slug":"invalid-attr-format-s-expected-name-value","errorCode":null,"errorMessage":"invalid attr format [%s], expected name=value","messagePattern":"invalid attr format \\[(.+?)\\], expected name=value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/cli/cmd/attr.go","lineNumber":89,"sourceCode":"Examples:\n  siyuan-kernel attr set --id 20260605100657-v080a4j --attr icon=1f4ca\n  siyuan-kernel attr set --id 20260605100657-v080a4j --attr title-img='background-image:url(\"assets/example.jpg\")'`,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tid, _ := cmd.Flags().GetString(\"id\")\n\t\tif id == \"\" {\n\t\t\treturn fmt.Errorf(\"--id is required\")\n\t\t}\n\n\t\tattrFlags, _ := cmd.Flags().GetStringArray(\"attr\")\n\t\tif len(attrFlags) == 0 {\n\t\t\treturn fmt.Errorf(\"--attr is required (format: name=value)\")\n\t\t}\n\n\t\tnameValues := make(map[string]string, len(attrFlags))\n\t\tfor _, a := range attrFlags {\n\t\t\tparts := strings.SplitN(a, \"=\", 2)\n\t\t\tif len(parts) != 2 {\n\t\t\t\treturn fmt.Errorf(\"invalid attr format [%s], expected name=value\", a)\n\t\t\t}\n\t\t\tnameValues[strings.TrimSpace(parts[0])] = parts[1]\n\t\t}\n\n\t\tif dryRun {\n\t\t\tvar parts []string\n\t\t\tfor k, v := range nameValues {\n\t\t\t\tparts = append(parts, fmt.Sprintf(\"%s=%s\", k, v))\n\t\t\t}\n\t\t\tfmt.Printf(\"[dry-run] Would set attributes on block %s: %s\\n\", id, strings.Join(parts, \", \"))\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := model.SetBlockAttrs(id, nameValues); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tmodel.AppendPushReloadFiletreeEntry()\n\t\tfmt.Println(\"ok\")","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/cli/cmd/attr.go#L71-L107","documentation":"Thrown inside the `attr set` loop that parses each `--attr` entry with `strings.SplitN(a, \"=\", 2)`. If an entry has no `=` separator, `SplitN` returns a one-element slice and the guard `len(parts) != 2` rejects it. The offending raw value is interpolated so the user sees exactly which token failed.","triggerScenarios":"Passing `--attr icon` (no `=`), `--attr =val` or `--attr key` without a value. Any token that does not contain at least one `=` sign triggers it.","commonSituations":"Using a space instead of `=`; quoting the whole flag so the shell strips the `=`; passing a flag-style value like `--attr --icon`; mistakenly thinking the flag takes a key only.","solutions":["Rewrite the token as `name=value`, e.g. `--attr icon=1f4ca`","If the value contains `=`, that is fine — only the FIRST `=` is the separator (SplitN limit 2)","Quote values with spaces: `--attr title-img='background-image:url(\"a.jpg\")'`","Inspect the bracketed token in the message to see which entry failed"],"exampleFix":"// before\nsiyuan-kernel attr set --id <id> --attr icon\n// after\nsiyuan-kernel attr set --id <id> --attr icon=1f4ca","handlingStrategy":"validation","validationCode":"// Validate each name=value token before passing it to the CLI.\nfor _, a := range attrTokens {\n    if !strings.Contains(a, \"=\") {\n        return fmt.Errorf(\"attr token %q lacks '=' separator\", a)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always construct `--attr` tokens as `name=value` in code, never by concatenation that may drop the `=`","Quote values containing spaces or special characters","Surface the failed token to the user so they can correct the specific entry"],"tags":["cli","attr","argument-parsing","go"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}