Skip to content

[Bug]: Type mismatch for custom field plugin values between schema and Management API #617

@negprof

Description

@negprof

Package

Other / Unknown

Bug Description

There seems to be a type mismatch for custom field plugin values between the component schema/types and the actual Storyblok Management API payload.

For a custom field plugin, the component schema can contain a default_value like this:

"default_value": "Test Value"

However, the actual story content expected by the Management API / validation can require the custom field value to be an object:


"backgroundColor": {
  "styles": {},
  "class": ""
}

In our case, the field is a custom color picker field plugin named backgroundColor inside a section component. When the field is untouched, the story payload can contain:

"backgroundColor": ""

Saving then fails with:

{
  "content": [
    "The value of the field backgroundColor in the component section with the uid <uid> must be an object"
  ]
}

This is confusing because the schema/default configuration appears to require stringified JSON, while the actual story content validation expects an object.

Expected behavior

There should be a consistent and documented way to define object-shaped default values for custom field plugins.

Either:

"default_value": {
  "styles": {},
  "class": ""
}

should be supported for custom field plugins, or the docs/types should clearly explain that default_value must be stringified JSON and how/when Storyblok parses it into the actual object value.

Actual behavior

default_value appears to be typed/configured as a string, but story content validation expects an object. If the field is untouched, Storyblok may serialize the custom field as an empty string, causing a validation error.

Questions

  • What is the correct type for default_value on custom field plugin fields?
  • Is stringified JSON supposed to be parsed into an object for plugin content?
  • How should object-shaped custom field plugin defaults be configured?
  • Should the schema/types for custom field plugins allow object defaults when the field content is expected to be an object?

Important: The plugin is not mounted in this case, because its nested inside an component or can be placed inside an "Tab".

Steps to Reproduce

  1. Create a component, for example section.

  2. Add a custom field plugin field, for example backgroundColor.

  3. Configure the field plugin so the expected story content value is an object, for example:

    {
      "styles": {},
      "class": ""
    }
  4. Place the custom field plugin inside a tab or another UI area that is not mounted/opened by default, for example a tab called background.

  5. In the component schema, configure a default_value for the custom field plugin. Since default_value is typed as a string, this has to be stringified JSON, for example:
    "default_value": "{\"styles\": {}, \"class\": \"\"}"

  6. Create a new story using the component.

  7. Do not open the tab containing the custom field plugin.

  8. Save or publish the story.

  9. Inspect the outgoing story payload or the Management API response.

Reproduction URL

No response

Expected Behavior

Expected Behavior

  • Custom field plugin values should have consistent types between the component schema, Visual Editor save payload, and Management API response.

  • If a custom field plugin is expected to store an object, Storyblok should initialize and serialize the field as an object, not as an empty string.

  • This should also work when the custom field plugin iframe is not mounted, for example when the field is inside an unopened tab.

  • The configured default value should be applied before save/publish, even if the plugin itself never mounted.

  • The save payload should contain an object value, for example:

    "backgroundColor": {
      "styles": {},
      "class": ""
    }
    
  • The story should save/publish successfully without requiring the editor to first open the tab containing the custom field plugin.

  • If object-shaped defaults are not supported for custom field plugins, the schema/types and documentation should clearly explain the correct way to define such defaults.

Actual Behavior

Actual Result

  • When the custom field plugin is inside an unopened tab, the plugin iframe is not mounted.
  • Because the plugin is not mounted, its code cannot run and cannot normalize the value via actions.setContent(...).
  • The field value remains an empty string in the story payload:

"backgroundColor": ""

  • Saving or publishing the story fails with a validation error:
  • The editor can only avoid the error by opening the tab containing the custom field plugin first, which causes the plugin iframe to mount and normalize the value.
  • This creates a mismatch: the schema/default value is configured as a stringified value, but the Visual Editor save validation expects the actual field content to be an object.

Environment

System:
    OS: macOS 15.7.4
    CPU: (12) arm64 Apple M4 Pro
    Memory: 121.42 MB / 24.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.11.0 - /opt/homebrew/bin/node
    npm: 10.9.2 - /opt/homebrew/bin/npm
    pnpm: 10.11.0 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 148.0.7778.168
    Safari: 26.4
  npmPackages:
    @storyblok/react: ^6.1.2 => 6.1.7 
    @storyblok/richtext: ^4.1.2 => 4.3.1 
    next: 16.2.6 => 16.2.6 
    react: 19.2.6 => 19.2.6

Error Logs

{
    "content": [
        "The value of the field stylePlugin in the component section with the uid 583cbcae-f0fc-49ba-9896-a3904ba43e54 must be an object"
    ]
}

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions