mattermost-community/focalboard · error

invalid property

Error message

invalid property

What it means

ErrInvalidProperty indicates a property referenced by a card does not exist in the board's property schema, or a properties map cannot be parsed correctly. It is returned by GetPropertyString, GetValue, and ParseProperties. The library throws it so callers know a property key/value pair cannot be resolved against the board's defined schema.

Source

Thrown at server/model/properties.go:19

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

//go:generate mockgen -destination=mocks/propValueResolverMock.go -package mocks . PropValueResolver

package model

import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"

	"github.com/mattermost/focalboard/server/utils"
)

var ErrInvalidBoardBlock = errors.New("invalid board block")
var ErrInvalidPropSchema = errors.New("invalid property schema")
var ErrInvalidProperty = errors.New("invalid property")
var ErrInvalidPropertyValue = errors.New("invalid property value")
var ErrInvalidPropertyValueType = errors.New("invalid property value type")
var ErrInvalidDate = errors.New("invalid date property")

// PropValueResolver allows PropDef.GetValue to further decode property values, such as
// looking up usernames from ids.
type PropValueResolver interface {
	GetUserByID(userID string) (*User, error)
}

// BlockProperties is a map of Prop's keyed by property id.
type BlockProperties map[string]BlockProp

// BlockProp represent a property attached to a block (typically a card).
type BlockProp struct {
	ID    string `json:"id"`
	Index int    `json:"index"`
	Name  string `json:"name"`

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Remove the stale property key from the card, or re-add the missing property definition to the board's cardProperties.
  2. When copying cards across boards, remap property ids to the target board's schema first.
  3. Verify the property id used matches an existing cardProperties entry exactly.
  4. Wrap reads with errors.Is(err, model.ErrInvalidProperty) and skip/treat as empty instead of failing the whole request.

Example fix

// before: blind read panics on missing schema entry
val, err := card.FieldValueAsString(props, "stale_prop_id")
// after
if _, ok := board.CardProperties["stale_prop_id"]; !ok {
    return "", nil // property no longer defined on this board
}
val, err := card.FieldValueAsString(props, "stale_prop_id")
Defensive patterns

Strategy: try-catch

Validate before calling

func propDefined(board *model.Board, key string) bool {
    _, ok := board.CardProperties[key]
    return ok
}
// check before reading: if !propDefined(board, key) { skip }

Type guard

func propertyExists(board *model.Board, key string) bool {
    _, ok := board.CardProperties[key]
    return ok
}

Try / catch

val, err := GetValue(resolver, board, props, key)
if errors.Is(err, model.ErrInvalidProperty) {
    val = "" // property no longer in schema; treat as unset
}

Prevention

When it happens

Trigger: Looking up a property value via GetPropertyString/GetValue with a key absent from the board's cardProperties, or calling ParseProperties on a card whose properties map references undefined schema entries.

Common situations: A board property was deleted while cards still carry the old key, cards copied between boards with different schemas, or plugin/API clients referencing hand-crafted property ids.

Related errors


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