mattermost-community/focalboard · error
card limit value is invalid
Error message
card limit value is invalid
What it means
ErrInvalidCardLimitValue indicates the card limit timestamp stored in the system_settings table is not a valid integer. getCardLimitTimestamp reads the value and returns this sentinel when strconv.Atoi fails. The library throws it so callers know the cloud card-limit feature cannot determine the cutoff timestamp.
Source
Thrown at server/services/store/sqlstore/cloud.go:16
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package sqlstore
import (
"database/sql"
"errors"
"strconv"
sq "github.com/Masterminds/squirrel"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/services/store"
)
var ErrInvalidCardLimitValue = errors.New("card limit value is invalid")
// activeCardsQuery applies the necessary filters to the query for it
// to fetch an active cards window if the cardLimit is set, or all the
// active cards if it's 0.
func (s *SQLStore) activeCardsQuery(builder sq.StatementBuilderType, selectStr string, cardLimit int) sq.SelectBuilder {
query := builder.
Select(selectStr).
From(s.tablePrefix + "blocks b").
Join(s.tablePrefix + "boards bd on b.board_id=bd.id").
Where(sq.Eq{
"b.delete_at": 0,
"b.type": model.TypeCard,
"bd.is_template": false,
})
if cardLimit != 0 {
query = query.
Limit(1).View on GitHub (pinned to a84bbb65e3)
Solutions
- Reset the card_limit_timestamp row in system_settings to '0' (or delete the row; missing rows default to 0).
- Call updateCardLimitTimestamp to have the server recompute and store a valid value.
- Audit any scripts/tools that write to system_settings and ensure they store plain integers.
- Check errors.Is(err, ErrInvalidCardLimitValue) and fall back to card-limit-disabled behavior.
Example fix
-- before: corrupted value SELECT value FROM system_settings WHERE id='card_limit_timestamp'; -- 'abc' -- after UPDATE system_settings SET value='0' WHERE id='card_limit_timestamp';
Defensive patterns
Strategy: try-catch
Validate before calling
// verify stored setting is numeric before relying on it
row, _ := db.Query("SELECT value FROM system_settings WHERE id='CardLimitTimestamp'")
var v string
_ = row.Scan(&v)
if _, err := strconv.Atoi(v); err != nil {
// reset to 0
db.Exec("UPDATE system_settings SET value='0' WHERE id='CardLimitTimestamp'")
} Type guard
func isIntString(s string) bool {
_, err := strconv.Atoi(s)
return err == nil
} Try / catch
ts, err := store.GetCardLimitTimestamp()
if errors.Is(err, sqlstore.ErrInvalidCardLimitValue) {
log.Warn("corrupt card limit timestamp; card limit disabled")
ts = 0
} Prevention
- Never hand-edit the system_settings table.
- Write the card limit setting only through the server API.
- Restore-with-validation after DB restores.
- Fall back to 0 (limit disabled) on parse failure.
When it happens
Trigger: Reading getCardLimitTimestamp when the CardLimitTimestamp system_settings row contains a non-numeric string (corrupted write, manual edit, or value written by incompatible code).
Common situations: Manual DB manipulation of system_settings, restore from a backup with a stale/mangled row, or a bug writing the setting as a formatted string instead of an integer.
Related errors
- database type is unsupported
- cannot notify block subscribers for block %s: %w
- cannot upsert notification hint: %w
- Unable to create the new user
- unable to update password
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/941d1e0fe7e92515.
Report an issue: GitHub.