{"record":{"id":"82f8dd6219ca4701","repo":"apache/superset","slug":"ex-message","errorCode":null,"errorMessage":"{ex.message}","messagePattern":"\\{ex\\.message\\}","errorType":"exception","errorClass":"SqlLabPermalinkGetFailedError","httpStatus":500,"severity":"error","filePath":"superset/commands/sql_lab/permalink/get.py","lineNumber":68,"sourceCode":"                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:\n        pass\n","sourceCodeStart":50,"sourceCodeEnd":72,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/sql_lab/permalink/get.py#L50-L72","documentation":"For modern (non-'kv:') permalink keys, GetSqlLabPermalinkCommand decodes the key with the configured salt and fetches the value via KeyValueDAO. Decode/codec errors, missing datasets referenced by the permalink, and KV get failures (DatasetNotFoundError, KeyValueCodecDecodeException, KeyValueGetFailedError, KeyValueParseKeyError) are re-raised as SqlLabPermalinkGetFailedError carrying the inner error's message (get.py:68).","triggerScenarios":"GET /api/v1/sqllab/permalink/<key> with a base64/hashed key that was signed with a different salt (SQLLAB_permalink salt / SECRET_KEY changed between create and read); a permalink that embeds a dataset id which has since been deleted; corrupted or tampered permalink payload that fails codec decoding.","commonSituations":"SECRET_KEY was rotated or the deployment was rebuilt without preserving config, invalidating all existing permalinks; dataset deleted or re-created with a new id after the permalink was shared; user hand-modified the permalink fragment in the URL.","solutions":["If SECRET_KEY or the permalink salt changed, old permalinks are unrecoverable — create a new permalink and update shared links; keep the SECRET_KEY stable across restarts to prevent recurrence","Verify any dataset referenced by the permalink still exists (restore or re-create it with the same id), otherwise re-generate the permalink","Treat decode failures on user-supplied keys as 4xx input errors: validate key format/length before calling the command","Check ex.message in logs to distinguish salt mismatch (decode failure) from missing dataset (DatasetNotFoundError)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    GetSqlLabPermalinkCommand(key).run()\nexcept SqlLabPermalinkGetFailedError:\n    show_permalink_expired_ui()  # salt mismatch or deleted dataset; regenerate link","preventionTips":["Keep SECRET_KEY and the permalink salt stable across restarts/upgrades","When rotating secrets, accept that old permalinks expire and communicate it","Verify referenced datasets still exist before relying on old permalinks"],"tags":["permalink","secret-key","key-value","sql-lab"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}