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

  1. Reset the card_limit_timestamp row in system_settings to '0' (or delete the row; missing rows default to 0).
  2. Call updateCardLimitTimestamp to have the server recompute and store a valid value.
  3. Audit any scripts/tools that write to system_settings and ensure they store plain integers.
  4. 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

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


AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30). Data as JSON: /api/errors/941d1e0fe7e92515. Report an issue: GitHub.