{"record":{"id":"d2995d4f5ad4e26c","repo":"OtterMind/Chat2DB","slug":"mysql-account-grantsunavailable","errorCode":"mysql.account.grantsUnavailable","errorMessage":"mysql.account.grantsUnavailable","messagePattern":"mysql\\.account\\.grantsUnavailable","errorType":"exception","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/account/MysqlAccountManager.java","lineNumber":61,"sourceCode":"    @Override\n    public List<AccountInfo> listAccounts(Connection connection) {\n        try {\n            return queryAccounts(connection, true);\n        } catch (SQLException lockedColumnError) {\n            try {\n                return queryAccounts(connection, false);\n            } catch (SQLException e) {\n                throw new BusinessException(ERROR_KEY_ACCOUNT_LIST_UNAVAILABLE, null, e);\n            }\n        }\n    }\n\n    @Override\n    public List<String> showGrants(Connection connection, String user, String host) {\n        try {\n            return queryGrants(connection, user, host);\n        } catch (SQLException e) {\n            throw new BusinessException(ERROR_KEY_ACCOUNT_GRANTS_UNAVAILABLE, null, e);\n        }\n    }\n\n    @Override\n    public AccountPreview preview(AccountOperationRequest command) {\n        String sql = MysqlAccountSqlBuilder.buildSql(command);\n        AccountPreview preview = new AccountPreview();\n        preview.setActionType(command.getActionType());\n        preview.setSql(MysqlAccountSqlBuilder.buildDisplaySql(command));\n        preview.setPreviewToken(MysqlAccountSqlBuilder.previewToken(sql));\n        return preview;\n    }\n\n    @Override\n    public AccountExecuteResponse execute(Connection connection, AccountOperationRequest command) {\n        AccountPreview preview = preview(command);\n        if (!StringUtils.equals(preview.getPreviewToken(), command.getPreviewToken())) {\n            throw new BusinessException(ERROR_KEY_ACCOUNT_PREVIEW_TOKEN_MISMATCH);","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-plugins/chat2db-community-mysql/src/main/java/ai/chat2db/plugin/mysql/account/MysqlAccountManager.java#L43-L79","documentation":"Thrown by MysqlAccountManager.showGrants when the underlying 'SHOW GRANTS' query fails. The SQLException is wrapped in BusinessException('mysql.account.grantsUnavailable') so the caller receives a localized message while the original SQL error is preserved as the cause. It fires when the user cannot run SHOW GRANTS for the requested account.","triggerScenarios":"showGrants(connection, user, host) where queryGrants throws: the connected user lacks privilege to view grants for the target account (SHOW GRANTS requires viewing your own grants unless you have SELECT on mysql or broader rights), the user/host arguments are malformed, or the connection dropped.","commonSituations":"An admin viewing another user's grants while connected as a non-privileged account; passing a host of '%' that does not match any row; a connection that lost its session; SHOW GRANTS FOR with a non-existent account returns an error.","solutions":["Connect with an account that has rights to inspect other users' grants (e.g. SELECT on mysql or a DBA role).","Confirm the user/host pair corresponds to an existing account (listAccounts first).","Inspect BusinessException.getCause() for the SQLException to distinguish 'no such account' from a privilege denial.","Handle the empty/failed result gracefully in the UI rather than crashing the grants panel."],"exampleFix":"// before\nList<String> grants = accountManager.showGrants(connection, user, host);\n\n// after\nList<String> grants;\ntry {\n    grants = accountManager.showGrants(connection, user, host);\n} catch (BusinessException e) {\n    if (\"mysql.account.grantsUnavailable\".equals(e.getCode())) {\n        log.warn(\"Cannot load grants for {}@{}: {}\", user, host, rootMessage(e.getCause()));\n        grants = Collections.emptyList();\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the account exists and the user can inspect grants before calling.\nif (!accountExists(connection, user, host)) {\n    return Collections.emptyList();\n}","typeGuard":null,"tryCatchPattern":"try {\n    return accountManager.showGrants(connection, user, host);\n} catch (BusinessException e) {\n    if (\"mysql.account.grantsUnavailable\".equals(e.getCode())) {\n        log.warn(\"grants unavailable for {}@{}: {}\", user, host, rootMessage(e.getCause()));\n        return Collections.emptyList();\n    }\n    throw e;\n}","preventionTips":["Connect with an account that can inspect other users' grants.","Verify the user/host pair exists before querying grants.","Inspect the wrapped cause to distinguish denial from missing account.","Render an empty grants panel rather than crashing on failure."],"tags":["mysql","account","privilege","grants"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}