{"record":{"id":"db77a8a4ebb5b5d8","repo":"chenhg5/cc-connect","slug":"tuitui-history-limit-must-be-non-negative","errorCode":null,"errorMessage":"tuitui: history_limit must be non-negative","messagePattern":"tuitui: history_limit must be non-negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/tuitui/tuitui.go","lineNumber":145,"sourceCode":"\tgroupPolicy = strings.ToLower(strings.TrimSpace(groupPolicy))\n\tswitch groupPolicy {\n\tcase \"allowlist\", \"open\", \"disabled\":\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"tuitui: invalid group_policy %q (want allowlist, open, or disabled)\", groupPolicy)\n\t}\n\trequireMention := true\n\tif v, ok := opts[\"require_mention\"].(bool); ok {\n\t\trequireMention = v\n\t}\n\treceiveReaction := \"收到\"\n\tif v, ok := opts[\"receive_reaction\"].(string); ok {\n\t\treceiveReaction = strings.TrimSpace(v)\n\t}\n\tshareSessionInChannel, _ := opts[\"share_session_in_channel\"].(bool)\n\tpendingHistoryLimit := defaultHistoryLimit\n\tif v, ok := intOption(opts[\"history_limit\"]); ok {\n\t\tif v < 0 {\n\t\t\treturn nil, fmt.Errorf(\"tuitui: history_limit must be non-negative\")\n\t\t}\n\t\tpendingHistoryLimit = v\n\t}\n\n\treturn &Platform{\n\t\tappID:                 appID,\n\t\tappSecret:             appSecret,\n\t\tapiBase:               strings.TrimRight(apiBase, \"/\"),\n\t\twsBase:                strings.TrimRight(wsBase, \"/\"),\n\t\tallowFrom:             allowFrom,\n\t\tgroupAllowFrom:        groupAllowFrom,\n\t\tignoreFrom:            ignoreFrom,\n\t\tgroupPolicy:           groupPolicy,\n\t\treceiveReaction:       receiveReaction,\n\t\trequireMention:        requireMention,\n\t\tshareSessionInChannel: shareSessionInChannel,\n\t\tpendingHistoryLimit:   pendingHistoryLimit,\n\t\tclient:                &http.Client{Timeout: httpTimeout},","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/tuitui/tuitui.go#L127-L163","documentation":"New() validates the optional \"history_limit\" option before constructing the Platform. The option is accepted via intOption and must be a non-negative integer because it caps how many historical messages the platform keeps/loads. A negative value is meaningless for a count, so construction fails fast with this error rather than misbehaving later.","triggerScenarios":"Calling tuitui.New (directly or via loadTuiTuiPlatform / core.CreatePlatform) with opts containing \"history_limit\" set to a negative integer such as -1, or a negative value loaded from config.toml.","commonSituations":"Config typo where a user writes history_limit = -1 thinking it disables history tracking; a script computing the limit from a difference that went negative; environment/config templating substituting an empty or sentinel value that parses to a negative number.","solutions":["Set \"history_limit\" to a non-negative integer in the platform options/config (or remove the key to use defaultHistoryLimit).","If the intent was to disable history, omit the \"history_limit\" option entirely instead of passing a negative number.","Clamp or validate the value at the config-loading layer before calling New."],"exampleFix":"// before\nopts[\"history_limit\"] = -1\np, err := tuitui.New(opts)\n// after\nopts[\"history_limit\"] = 0 // or omit the key to use the default\np, err := tuitui.New(opts)","handlingStrategy":"validation","validationCode":"if v, ok := opts[\"history_limit\"].(int); ok && v < 0 {\n    return fmt.Errorf(\"history_limit must be >= 0, got %d\", v)\n}","typeGuard":"func validHistoryLimit(v int) bool { return v >= 0 }","tryCatchPattern":null,"preventionTips":["Validate all integer config fields at startup, before constructing platforms.","Omit optional keys instead of using negative sentinels.","Add a config lint step that rejects negative counts."],"tags":["config","validation","platform"],"backgroundTag":"invalid-config-value","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}