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
- 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.
- Do not pass arbitrary string keys; if you need namespaced keys, store them as part of the encoded value or add a dedicated column.
- Inspect the exception's __cause__ to confirm the ValueError came from key assignment, then fix the key type at the call site.
- 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
- Derive keys from one helper per resource so the UUID/int choice is encoded in one place.
- Never use random string keys where the schema declares int or UUID columns.
- When using explicit keys plus expires_on, call delete_expired_entries first as documented.
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
- Datasource value is neither id or uuid
- Duplicate UUID in folder structure: {uuid}
- Invalid UUID: {uuid}
- Invalid filter: column '%s' does not exist on %s
- Operator '{operator_enum.value}' on relationship column '{co
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/ea9f97fef9206543.
Report an issue: GitHub.