{"record":{"id":"056ca953e963dd41","repo":"siyuan-note/siyuan","slug":"field-mode-must-be-0-or-1","errorCode":null,"errorMessage":"Field [mode] must be 0 or 1","messagePattern":"Field \\[mode\\] must be 0 or 1","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/bazaar.go","lineNumber":928,"sourceCode":"\t\tif request.PackageName, err = bazaarString(fields, \"packageName\", true, true); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\t_, hasMode := fields[\"mode\"]\n\t\t_, hasModeOS := fields[\"modeOS\"]\n\t\tif hasMode != hasModeOS {\n\t\t\treturn request, errors.New(\"Fields [mode] and [modeOS] must be provided together\")\n\t\t}\n\t\tif hasMode {\n\t\t\tmode, parseErr := legacyField[float64](fields, \"mode\", \"Number\", true)\n\t\t\tif parseErr != nil {\n\t\t\t\treturn request, parseErr\n\t\t\t}\n\t\t\tmodeOS, parseErr := legacyField[bool](fields, \"modeOS\", \"Boolean\", true)\n\t\t\tif parseErr != nil {\n\t\t\t\treturn request, parseErr\n\t\t\t}\n\t\t\tif mode != 0 && mode != 1 {\n\t\t\t\treturn request, errors.New(\"Field [mode] must be 0 or 1\")\n\t\t\t}\n\t\t\trequest.Mode = &mode\n\t\t\trequest.ModeOS = &modeOS\n\t\t}\n\t\treturn request, nil\n\t}\n\tUninstallBazaarTheme.decodeRequest = func(reader io.Reader) (request UninstallBazaarThemeRequest, err error) {\n\t\tfields, err := bazaarRequestFields(reader, \"/api/bazaar/uninstallBazaarTheme\")\n\t\tif err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\tif request.Frontend, err = bazaarString(fields, \"frontend\", false, false); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\tif request.Keyword, err = bazaarString(fields, \"keyword\", false, false); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\tif request.PackageName, err = bazaarString(fields, \"packageName\", true, true); err != nil {","sourceCodeStart":910,"sourceCodeEnd":946,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/bazaar.go#L910-L946","documentation":"When the optional mode field is supplied to the bazaar install endpoint, its numeric value must be exactly 0 or 1. Any other number (or non-integer numeric JSON) is rejected by the decoder before reaching the handler, since mode is a two-value selector, not a free integer.","triggerScenarios":"POSTing to the bazaar install endpoint with {\"packageName\":\"x\",\"mode\":2,\"modeOS\":true} or mode values like -1, 1.5, or a numeric string \"0\" sent as an actual number.","commonSituations":"Clients guessing mode semantics and using 2 for 'both', enum-like constants from other APIs (0/1/2 conventions), or mapping internal flags (bitmasks) directly onto mode.","solutions":["Set mode to exactly 0 (app) or 1 (plugin/frontend context).","Map your internal value to the supported 0/1 domain before sending.","If you need more states than 0/1, omit mode/modeOS entirely instead of inventing values.","Log and clamp the value at the client boundary."],"exampleFix":"// before\n{\"packageName\": \"siyuan-plugin-x\", \"mode\": 2, \"modeOS\": false}\n// after\n{\"packageName\": \"siyuan-plugin-x\", \"mode\": 1, \"modeOS\": false}","handlingStrategy":"validation","validationCode":"if (payload.mode !== undefined && ![0, 1].includes(payload.mode)) {\n  throw new Error(\"mode must be 0 or 1\");\n}","typeGuard":"const isMode = (v) => v === 0 || v === 1;","tryCatchPattern":null,"preventionTips":["Model mode as a boolean or two-value enum on the client","Clamp/map internal state values to 0/1 at the boundary","Document that mode is a selector, not a free integer","Reject out-of-domain values in form validation before submit"],"tags":["validation","enum","api","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}