mattermost-community/focalboard · warning

invalid property value type

Error message

invalid property value type

What it means

ErrInvalidPropertyValueType is returned when the raw JSON value of a property has a type that does not match the property definition type, e.g. a string where the schema expects an array for multi-select. GetPropertyString and GetValue throw it during type-checked decoding. It prevents type-confusion when reading property values.

Source

Thrown at server/model/properties.go:21

//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"`
	Value string `json:"value"`
}

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Correct the stored value's JSON type to match the property definition type.
  2. Restore the original property type in cardProperties if it was changed unintentionally.
  3. Write a migration to convert old values to the new type after changing a property type.
  4. Use errors.Is(err, model.ErrInvalidPropertyValueType) on reads to skip mismatched values instead of failing.

Example fix

// before: property type changed to multi-select but value is a string
props["tags"] = "urgent"
// after: store the array shape the type requires
props["tags"] = []string{"opt_urgent"}
Defensive patterns

Strategy: type-guard

Validate before calling

func valueMatchesType(def model.PropDef, raw json.RawMessage) bool {
    switch def.Type {
    case "multiSelect":
        var arr []string
        return json.Unmarshal(raw, &arr) == nil
    case "number":
        var n float64
        return json.Unmarshal(raw, &n) == nil
    default:
        var s string
        return json.Unmarshal(raw, &s) == nil
    }
}

Type guard

func isStringArray(raw json.RawMessage) bool {
    var arr []string
    return json.Unmarshal(raw, &arr) == nil
}

Try / catch

val, err := GetValue(resolver, board, props, key)
if errors.Is(err, model.ErrInvalidPropertyValueType) {
    log.Warn("property value type mismatch", "key", key)
    val = ""
}

Prevention

When it happens

Trigger: Reading a property whose JSON value cannot be cast to the type dictated by PropDef.Type (e.g. number stored as object, select stored as array), via GetValue or GetPropertyString.

Common situations: A property's type was changed in cardProperties after cards already stored old-typed values, migrations between versions, or external writes to the DB with mismatched JSON types.

Related errors


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