OtterMind/Chat2DB · error · BusinessException
database.delete.systemSchemaForbidden
database.delete.systemSchemaForbidden
Error message
database.delete.systemSchemaForbidden
What it means
Thrown by rejectSystemSchema when the active dbType is PostgreSQL and the schema name matches a protected system schema (pg_catalog, information_schema, public) or starts with pg_toast or pg_temp (case-insensitive). These schemas are internal to PostgreSQL and dropping them corrupts the database. Fires in both prepare and execute paths.
Source
Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDatabaseObjectDeleteServiceImpl.java:244
private String buildDropDatabase(String dbType, String databaseName) {
return Chat2DBContext.getDbMetaData(dbType).getSqlBuilder().ddl().database().buildDropDatabase(databaseName);
}
private void assertSchemaDeletionSupported(String dbType) {
DBConfig dbConfig = Chat2DBContext.getDBConfig(dbType);
if (dbConfig == null || !dbConfig.isSupportSchema()
|| !DatabaseTypeEnum.POSTGRESQL.name().equalsIgnoreCase(dbType)) {
throw new BusinessException("database.delete.notSupportSchema");
}
}
private void rejectSystemSchema(String dbType, String schemaName) {
if (DatabaseTypeEnum.POSTGRESQL.name().equalsIgnoreCase(dbType)) {
String lowerSchemaName = StringUtils.lowerCase(schemaName);
if (POSTGRESQL_SYSTEM_SCHEMAS.contains(lowerSchemaName)
|| StringUtils.startsWith(lowerSchemaName, "pg_toast")
|| StringUtils.startsWith(lowerSchemaName, "pg_temp")) {
throw new BusinessException("database.delete.systemSchemaForbidden");
}
}
}
private void assertSchemaExists(Connection connection, String databaseName, String schemaName) {
List<Schema> schemas = Chat2DBContext.getDbMetaData().schemas(connection, databaseName);
boolean exists = schemas != null && schemas.stream()
.anyMatch(schema -> StringUtils.equals(schema.getName(), schemaName));
if (!exists) {
throw new BusinessException("database.delete.schemaNotExists");
}
}
private String schemaConfirmName(String schemaName) {
return schemaName;
}
private String buildDropSchema(String dbType, String schemaName) {View on GitHub (pinned to 5ee1e990e7)
Solutions
- Never target pg_catalog, information_schema, public, pg_toast*, or pg_temp* for deletion.
- Filter these names from the schema list before presenting delete as an option.
- Create and delete only user-defined schemas.
Example fix
// before
prepareSchemaDelete(req); // schemaName='public'
// after
Set<String> blocked = Set.of("pg_catalog","information_schema","public");
String lower = StringUtils.lowerCase(req.getSchemaName());
if (blocked.contains(lower) || lower.startsWith("pg_toast") || lower.startsWith("pg_temp")) {
return; // skip system schemas
}
prepareSchemaDelete(req); Defensive patterns
Strategy: validation
Validate before calling
Set<String> pgSchemas = Set.of("pg_catalog","information_schema","public");
String lower = StringUtils.lowerCase(schemaName);
if ("POSTGRESQL".equalsIgnoreCase(dbType)
&& (pgSchemas.contains(lower) || lower.startsWith("pg_toast") || lower.startsWith("pg_temp"))) {
// skip / disable delete
} Prevention
- Filter system and temp schemas from the deletable schema list.
- Maintain a deny-list matching POSTGRESQL_SYSTEM_SCHEMAS plus the pg_toast/pg_temp prefixes.
When it happens
Trigger: Calling prepareSchemaDelete or executeSchemaDelete with schemaName equal to (case-insensitive) 'pg_catalog', 'information_schema', or 'public', or starting with 'pg_toast'/'pg_temp' on a PostgreSQL connection.
Common situations: User selects 'public' in the schema list and attempts delete; temp schema (pg_temp_N) appears in listings; pg_toast schemas leaked into UI.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- database.delete.notSupportSchema
- database.delete.confirmNameMismatch
- database.delete.systemDatabaseForbidden
- database.delete.schemaNotExists
- EWKB line string must be empty or contain at least two coord
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/1c5d74141837f4d4.
Report an issue: GitHub.