{"record":{"id":"c76adffc3ac3b654","repo":"apache/superset","slug":"error-msg-from-exception-ex","errorCode":null,"errorMessage":"{error_msg_from_exception(ex)}","messagePattern":"\\{error_msg_from_exception\\(ex\\)\\}","errorType":"exception","errorClass":"SqlLabPermalinkGetFailedError","httpStatus":500,"severity":"error","filePath":"superset/commands/sql_lab/permalink/get.py","lineNumber":52,"sourceCode":"\nlogger = logging.getLogger(__name__)\n\n\nclass GetSqlLabPermalinkCommand(BaseSqlLabPermalinkCommand):\n    def __init__(self, key: str):\n        self.key = key\n\n    def run(self) -> Optional[SqlLabPermalinkValue]:\n        self.validate()\n        if self.key.startswith(\"kv:\"):\n            id = int(self.key[3:])\n            try:\n                kv = db.session.query(models.KeyValue).filter_by(id=id).scalar()\n                if not kv:\n                    return None\n                return json.loads(kv.value)\n            except Exception as ex:\n                raise SqlLabPermalinkGetFailedError(\n                    message=utils.error_msg_from_exception(ex)\n                ) from ex\n\n        try:\n            key = decode_permalink_id(self.key, salt=self.salt)\n            value = KeyValueDAO.get_value(self.resource, key, self.codec)\n            if value:\n                return value\n            return None\n        except (\n            DatasetNotFoundError,\n            KeyValueCodecDecodeException,\n            KeyValueGetFailedError,\n            KeyValueParseKeyError,\n        ) as ex:\n            raise SqlLabPermalinkGetFailedError(message=ex.message) from ex\n\n    def validate(self) -> None:","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/sql_lab/permalink/get.py#L34-L70","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Validate the permalink key format before use: must match kv:<digits>; discard/repair malformed URLs","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","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","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.)"],"exampleFix":"# before\nGetSqlLabPermalinkCommand(key='kv:12ab').run()  # ValueError -> SqlLabPermalinkGetFailedError\n# after\nif re.fullmatch(r'kv:\\\\d+', key):\n    GetSqlLabPermalinkCommand(key=key).run()","handlingStrategy":"validation","validationCode":"import re\n\ndef is_wellformed_permalink_key(key: str) -> bool:\n    return bool(re.fullmatch(r'kv:\\\\d+', key)) or not key.startswith('kv:')","typeGuard":null,"tryCatchPattern":"try:\n    GetSqlLabPermalinkCommand(key).run()\nexcept SqlLabPermalinkGetFailedError as ex:\n    log.warning('permalink get failed: %s', ex.message)  # message carries root cause\n    return None  # degrade to 'permalink unavailable' UX","preventionTips":["Never hand-edit permalink URLs; copy them from the UI","Keep the metadata DB's key_value table intact across upgrades","Log the wrapped message — it names the actual failing operation"],"tags":["permalink","key-value","json","sql-lab"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}