apache/superset · error · KeyValueCreateFailedError

An error occurred while creating the value.

Error message

An error occurred while creating the value.

What it means

Raised by KeyValueDAO.create_entry when an explicit key is supplied but assigning it to the entry raises ValueError. The assignment branches on type: UUID keys go to entry.uuid, anything else goes to entry.id; entry.id is an integer column, so a non-UUID, non-integer key (e.g. a random string) makes SQLAlchemy/psycopg raise ValueError, which is re-raised as KeyValueCreateFailedError ('An error occurred while creating the value.'). The message is the generic CreateFailedError default, distinct from the encode failure message.

Source

Thrown at superset/daos/key_value.py:131

        try:
            encoded_value = codec.encode(value)
        except Exception as ex:
            raise KeyValueCreateFailedError("Unable to encode value") from ex
        entry = KeyValueEntry(
            resource=resource.value,
            value=encoded_value,
            created_on=datetime.now(),
            created_by_fk=get_user_id(),
            expires_on=expires_on,
        )
        if key is not None:
            try:
                if isinstance(key, UUID):
                    entry.uuid = key
                else:
                    entry.id = key
            except ValueError as ex:
                raise KeyValueCreateFailedError() from ex
        db.session.add(entry)
        return entry

    @staticmethod
    def upsert_entry(
        resource: KeyValueResource,
        value: Any,
        codec: KeyValueCodec,
        key: Key,
        expires_on: datetime | None = None,
    ) -> KeyValueEntry:
        """
        Update an existing entry or create it if it does not exist.

        Because this overwrites any existing entry for the key (expired or not), it
        does not require a prior :meth:`delete_expired_entries` call.
        """
        if entry := KeyValueDAO.get_entry(resource, key):

View on GitHub (pinned to f4587218dd)

Solutions

  1. Match the key type to the resource schema: pass a uuid.UUID (e.g. uuid.uuid4()) for UUID-keyed resources, an int for integer-keyed resources.
  2. Do not pass arbitrary string keys; if you need namespaced keys, store them as part of the encoded value or add a dedicated column.
  3. Inspect the exception's __cause__ to confirm the ValueError came from key assignment, then fix the key type at the call site.
  4. When creating entries with explicit keys and an expires_on, first call KeyValueDAO.delete_expired_entries for that resource as the docstring requires, so unique-constraint collisions on the same key do not surface as a different create failure.

Example fix

# before
KeyValueDAO.create_entry(resource, value, codec, key='tab-abc123')
# -> ValueError wrapped in KeyValueCreateFailedError

# after
import uuid
KeyValueDAO.create_entry(resource, value, codec, key=uuid.uuid4())  # UUID-keyed resource
KeyValueDAO.create_entry(resource, value, codec, key=42)  # int-keyed resource
Defensive patterns

Strategy: type-guard

Validate before calling

from uuid import UUID

def valid_kv_key(key) -> bool:
    return isinstance(key, UUID) or isinstance(key, int)

Type guard

from uuid import UUID

def is_valid_kv_key(key: object) -> TypeGuard[UUID | int]:
    return isinstance(key, (UUID, int))

Try / catch

from superset.key_value.commands.exceptions import KeyValueCreateFailedError
try:
    KeyValueDAO.create_entry(resource, value, codec, key=key)
except KeyValueCreateFailedError as err:
    if isinstance(err.__cause__, ValueError):
        # key type mismatch with the resource's key column
        key = uuid.uuid4()  # or int per resource schema, then retry once

Prevention

When it happens

Trigger: Calling create_entry(key='my-string-key', ...) for a resource whose key column expects int or UUID; passing an int-like string that SQLAlchemy still rejects in the column assignment path; mixing key types between resources (UUID-keyed dashboard tabs vs int-keyed entries) and reusing the wrong key object.

Common situations: Building a new key-value resource and generating keys with get_random_string() instead of uuid4()/ints; refactoring a resource from int keys to UUID keys while old callers still pass strings; copy-pasting the explicit-key code path from a UUID resource into an int-keyed one.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/ea9f97fef9206543. Report an issue: GitHub.