apache/superset · error · SqlLabPermalinkGetFailedError

{error_msg_from_exception(ex)}

Error message

{error_msg_from_exception(ex)}

What it means

In GetSqlLabPermalinkCommand.run(), legacy permalink keys prefixed 'kv:' are resolved by parsing the numeric id and loading the KeyValue row directly. Any exception during that lookup (bad int parse, missing table, JSON decode failure of kv.value, DB error) is wrapped into SqlLabPermalinkGetFailedError with the raw exception message (get.py:52).

Source

Thrown at superset/commands/sql_lab/permalink/get.py:52

logger = logging.getLogger(__name__)


class GetSqlLabPermalinkCommand(BaseSqlLabPermalinkCommand):
    def __init__(self, key: str):
        self.key = key

    def run(self) -> Optional[SqlLabPermalinkValue]:
        self.validate()
        if self.key.startswith("kv:"):
            id = int(self.key[3:])
            try:
                kv = db.session.query(models.KeyValue).filter_by(id=id).scalar()
                if not kv:
                    return None
                return json.loads(kv.value)
            except Exception as ex:
                raise SqlLabPermalinkGetFailedError(
                    message=utils.error_msg_from_exception(ex)
                ) from ex

        try:
            key = decode_permalink_id(self.key, salt=self.salt)
            value = KeyValueDAO.get_value(self.resource, key, self.codec)
            if value:
                return value
            return None
        except (
            DatasetNotFoundError,
            KeyValueCodecDecodeException,
            KeyValueGetFailedError,
            KeyValueParseKeyError,
        ) as ex:
            raise SqlLabPermalinkGetFailedError(message=ex.message) from ex

    def validate(self) -> None:

View on GitHub (pinned to f4587218dd)

Solutions

  1. Validate the permalink key format before use: must match kv:<digits>; discard/repair malformed URLs
  2. If this follows an upgrade, regenerate the permalink from a fresh SQL Lab state instead of relying on the legacy 'kv:' entry; run 'superset db upgrade' to ensure KV tables are current
  3. Inspect the key_value row in the metadata DB (SELECT value FROM key_value WHERE id=...) to see if the JSON is corrupted; delete the bad entry so clients get a clean 404 rather than a 500
  4. Check the wrapped exception message in logs — it is error_msg_from_exception(ex), so it names the true root cause (ValueError, JSONDecodeError, OperationalError, etc.)

Example fix

# before
GetSqlLabPermalinkCommand(key='kv:12ab').run()  # ValueError -> SqlLabPermalinkGetFailedError
# after
if re.fullmatch(r'kv:\\d+', key):
    GetSqlLabPermalinkCommand(key=key).run()
Defensive patterns

Strategy: validation

Validate before calling

import re

def is_wellformed_permalink_key(key: str) -> bool:
    return bool(re.fullmatch(r'kv:\\d+', key)) or not key.startswith('kv:')

Try / catch

try:
    GetSqlLabPermalinkCommand(key).run()
except SqlLabPermalinkGetFailedError as ex:
    log.warning('permalink get failed: %s', ex.message)  # message carries root cause
    return None  # degrade to 'permalink unavailable' UX

Prevention

When it happens

Trigger: GET /api/v1/sqllab/permalink/<key> where key starts with 'kv:' but the remainder is not a valid integer; the KeyValue row's value column contains malformed JSON; a metadata DB error occurs during the query; the key_value table does not exist.

Common situations: Hand-edited or truncated permalink URLs; upgrading Superset versions where the permalink storage format changed and old 'kv:' entries hold values the current json.loads cannot parse; metadata DB partially migrated.

Related errors


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