{"record":{"id":"a9f0560337ece04e","repo":"Wei-Shaw/sub2api","slug":"rate-multiplier-must-be-0","errorCode":null,"errorMessage":"rate_multiplier must be >= 0","messagePattern":"rate_multiplier must be >= 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/internal/handler/admin/account_data.go","lineNumber":697,"sourceCode":"\tif strings.TrimSpace(item.Name) == \"\" {\n\t\treturn errors.New(\"account name is required\")\n\t}\n\tif strings.TrimSpace(item.Platform) == \"\" {\n\t\treturn errors.New(\"account platform is required\")\n\t}\n\tif strings.TrimSpace(item.Type) == \"\" {\n\t\treturn errors.New(\"account type is required\")\n\t}\n\tif len(item.Credentials) == 0 {\n\t\treturn errors.New(\"account credentials is required\")\n\t}\n\tswitch item.Type {\n\tcase service.AccountTypeOAuth, service.AccountTypeSetupToken, service.AccountTypeAPIKey, service.AccountTypeUpstream:\n\tdefault:\n\t\treturn fmt.Errorf(\"account type is invalid: %s\", item.Type)\n\t}\n\tif item.RateMultiplier != nil && *item.RateMultiplier < 0 {\n\t\treturn errors.New(\"rate_multiplier must be >= 0\")\n\t}\n\tif item.Concurrency < 0 {\n\t\treturn errors.New(\"concurrency must be >= 0\")\n\t}\n\tif item.Priority < 0 {\n\t\treturn errors.New(\"priority must be >= 0\")\n\t}\n\treturn nil\n}\n\nfunc defaultProxyName(name string) string {\n\tif strings.TrimSpace(name) == \"\" {\n\t\treturn \"imported-proxy\"\n\t}\n\treturn name\n}\n\n// enrichCredentialsFromIDToken performs best-effort extraction of user info fields","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/Wei-Shaw/sub2api/blob/073e92d17178a1ccdb0a27017f572f10c9c7ab62/backend/internal/handler/admin/account_data.go#L679-L715","documentation":"Returned by validateDataAccount (backend/internal/handler/admin/account_data.go:697) when an accounts[] entry sets rate_multiplier to a negative number. The field is optional (nil passes) but when present must be >= 0; concurrency and priority have analogous non-negative checks immediately after.","triggerScenarios":"An account entry with \"rate_multiplier\": -1 or any negative value — typically from a form, spreadsheet, or computed value that went below zero.","commonSituations":"Spreadsheet formulas producing negative multipliers; UI number inputs without min=0; copy-paste of a minus sign or dash character; treating 0 as 'unlimited' and normalizing unset to -1.","solutions":["Set rate_multiplier to 0 or a positive value, or remove the field entirely to use the default.","Add min=\"0\" validation on the input that produces the value.","If unset should mean default, omit the key instead of sending a sentinel like -1."],"exampleFix":"// before\n{ \"name\": \"main\", \"platform\": \"openai\", \"type\": \"oauth\", \"credentials\": { ... }, \"rate_multiplier\": -0.5 }\n\n// after\n{ \"name\": \"main\", \"platform\": \"openai\", \"type\": \"oauth\", \"credentials\": { ... }, \"rate_multiplier\": 0.5 }","handlingStrategy":"validation","validationCode":"function hasValidRateMultiplier(entry: Record<string, unknown>): boolean {\n  const r = entry.rate_multiplier\n  return r === undefined || r === null || (typeof r === 'number' && r >= 0)\n}","typeGuard":"function isOptionalNonNegative(n: unknown): n is number | undefined {\n  return n === undefined || n === null || (typeof n === 'number' && n >= 0)\n}","tryCatchPattern":null,"preventionTips":["Use min=0 on numeric inputs; omit the field entirely for defaults.","Normalize 'unset' by removing the key, never by sending a negative sentinel.","Watch spreadsheet-derived values that can compute below zero."],"tags":["admin","import","account","validation","backend","numeric"],"backgroundTag":null,"analyzedSha":"073e92d17178a1ccdb0a27017f572f10c9c7ab62","analyzedAt":"2026-08-15T14:33:00.750Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}