HelloZeroNet/ZeroNet · error · Error

Style values must be strings

Error message

Style values must be strings

What it means

checkStyleValue enforces that every value in a vnode's `styles` object is a string. maquette deliberately does not coerce numbers (unlike React); unitless numeric values would be ambiguous (px vs raw), so non-string style values throw immediately during setProperties or updateProperties.

Source

Thrown at plugins/UiConfig/media/js/all.js:282

    };
    var DEFAULT_PROJECTION_OPTIONS = {
        namespace: undefined,
        eventHandlerInterceptor: undefined,
        styleApplyer: function (domNode, styleName, value) {
            // Provides a hook to add vendor prefixes for browsers that still need it.
            domNode.style[styleName] = value;
        },
        transitions: {
            enter: missingTransition,
            exit: missingTransition
        }
    };
    var applyDefaultProjectionOptions = function (projectorOptions) {
        return extend(DEFAULT_PROJECTION_OPTIONS, projectorOptions);
    };
    var checkStyleValue = function (styleValue) {
        if (typeof styleValue !== 'string') {
            throw new Error('Style values must be strings');
        }
    };
    var setProperties = function (domNode, properties, projectionOptions) {
        if (!properties) {
            return;
        }
        var eventHandlerInterceptor = projectionOptions.eventHandlerInterceptor;
        var propNames = Object.keys(properties);
        var propCount = propNames.length;
        for (var i = 0; i < propCount; i++) {
            var propName = propNames[i];
            /* tslint:disable:no-var-keyword: edge case */
            var propValue = properties[propName];
            /* tslint:enable:no-var-keyword */
            if (propName === 'className') {
                throw new Error('Property "className" is not supported, use "class".');
            } else if (propName === 'class') {
                if (domNode.className) {

View on GitHub (pinned to 454c0b2e7e)

Solutions

  1. Convert numeric values to strings with units: { height: '100px' } instead of { height: 100 }.
  2. Use String(value) or template literals when building styles dynamically.
  3. Add a runtime guard or TypeScript `Styles` typing to catch non-string values at authoring time.
  4. For truly unitless properties (opacity, zIndex) still pass strings: { opacity: '0.5' }.

Example fix

// before
h('div', { styles: { height: 100, opacity: 0.5 } })
// after
h('div', { styles: { height: '100px', opacity: '0.5' } })
Defensive patterns

Strategy: type-guard

Validate before calling

function assertStyles(styles) {
  if (!styles) return;
  Object.keys(styles).forEach(function (k) {
    if (typeof styles[k] !== 'string') throw new TypeError('style ' + k + ' must be a string, got ' + typeof styles[k]);
  });
}
// run before passing vnode to dom.append/projector

Type guard

function isStringStyles(styles) {
  return styles == null || Object.values(styles).every(function (v) { return typeof v === 'string'; });
}

Try / catch

try {
  projection.update(updatedVnode);
} catch (e) {
  if (e.message === 'Style values must be strings') {
    console.error('Non-string style value in vnode; coerce numbers to strings with units');
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a `styles` object with a numeric value, e.g. h('div', { styles: { height: 100 } }) or { opacity: 0.5 }, during initial render (setProperties) or a re-render (updateProperties).

Common situations: Coming from React where numeric style values are auto-suffixed with 'px'; generating styles programmatically where numbers slip in (JSON data, CSS calculations); TypeScript not enabled so the Styles type isn't checked.

Related errors


AI-assisted analysis of HelloZeroNet/ZeroNet@454c0b2e7e (2026-09-02). Data as JSON: /api/errors/e0793582fc3df698. Report an issue: GitHub.