siyuan-note/siyuan · error

inline styles must not be null

Error message

inline styles must not be null

What it means

setInlineStylesData is the single write path for the workspace inline-styles file (custom AV color palettes). It refuses a nil styles pointer because there is nothing to normalize, version-check, merge, or persist. The error is a caller-contract violation: callers (SetInlineStyles, SetInlineStylesData, SetWorkspaceAVPalette via replaceWorkspaceAVPalette) must pass a decoded InlineStyles value.

Source

Thrown at kernel/model/inline_style.go:231

			})
		}
		filteredHidden := current.Builtin.Hidden.AV[:0]
		for _, index := range current.Builtin.Hidden.AV {
			if index != patch.Index {
				filteredHidden = append(filteredHidden, index)
			}
		}
		current.Builtin.Hidden.AV = filteredHidden
		if patch.Hidden {
			current.Builtin.Hidden.AV = append(current.Builtin.Hidden.AV, patch.Index)
		}
	}
	return setInlineStylesData(current, currentAV)
}

func setInlineStylesData(styles *InlineStyles, currentAV *InlineStyleAV) (ret *InlineStyles, changed bool, err error) {
	if styles == nil {
		return nil, false, errors.New("inline styles must not be null")
	}
	if styles.Version != InlineStylesVersion {
		return nil, false, fmt.Errorf("unsupported inline styles version [%d]", styles.Version)
	}
	if currentAV == nil {
		currentAV = newEmptyInlineStyleAV()
	}

	normalizedStyles, err := normalizeInlineStyles(styles.Styles, true)
	if err != nil {
		return nil, false, err
	}
	normalizedBuiltin, err := normalizeInlineStyleBuiltin(styles.Builtin)
	if err != nil {
		return nil, false, err
	}
	normalizedAV, err := normalizeInlineStyleAV(styles.AV, true)
	if err != nil {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Ensure the caller constructs a valid *InlineStyles (at least an empty struct with Version = InlineStylesVersion) before calling
  2. If loading from disk, treat null/empty file content as newEmptyInlineStyleAV()/default styles instead of passing nil
  3. Decode into a non-pointer-initialized value and only call the setter when decoding succeeded
  4. Wrap the call and surface the error to the user instead of retrying with the same nil value

Example fix

// before
var styles *InlineStyles
ret, changed, err := SetInlineStyles(styles) // panics into error: inline styles must not be null
// after
styles := &InlineStyles{Version: InlineStylesVersion, Styles: map[string]*InlineStyle{}}
ret, changed, err := SetInlineStyles(styles)
Defensive patterns

Strategy: type-guard

Validate before calling

if styles == nil {
    styles = &InlineStyles{Version: InlineStylesVersion}
}
ret, changed, err := model.SetInlineStyles(styles)

Type guard

func validStyles(s *model.InlineStyles) bool { return s != nil && s.Version == model.InlineStylesVersion }

Try / catch

ret, changed, err := model.SetInlineStyles(styles)
if err != nil && strings.Contains(err.Error(), "must not be null") {
    styles = &model.InlineStyles{Version: model.InlineStylesVersion}
    ret, changed, err = model.SetInlineStyles(styles)
}

Prevention

When it happens

Trigger: Calling SetInlineStyles/SetInlineStylesData with a nil *InlineStyles, or an upstream JSON decode of the inline-styles file that yields nil (e.g. empty or 'null' file content decoded into a nil pointer) then passed back into the setter.

Common situations: Hand-editing or truncating storage/inline_styles (JSON 'null'/empty) and then triggering a palette update; a plugin or integration calling the API with an unset styles object; migration code that decodes old data into a nil struct.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/233d920b35669b5f. Report an issue: GitHub.