prestodb/presto · error · PrestoException

SCHEMA_ALREADY_EXISTS

SCHEMA_ALREADY_EXISTS

Error message

Schema '%s' already exists or created by others

What it means

InMemorySchemaStore.insert throws SCHEMA_ALREADY_EXISTS when a schema with the same (lowercased) name is already registered in the in-memory map. The store is a simple synchronized HashMap keyed by lowercase schema name, so duplicate registration is rejected rather than overwritten.

Source

Thrown at presto-lark-sheets/src/main/java/com/facebook/presto/lark/sheets/api/InMemorySchemaStore.java:44

import static java.lang.String.format;

public class InMemorySchemaStore
        implements LarkSheetsSchemaStore
{
    private final Map<String, LarkSheetsSchema> schemas = new ConcurrentHashMap<>();

    @Override
    public Optional<LarkSheetsSchema> get(String name)
    {
        return Optional.ofNullable(schemas.get(lower(name)));
    }

    @Override
    public synchronized void insert(LarkSheetsSchema schema)
    {
        String name = lower(schema.getName());
        if (schemas.containsKey(name)) {
            throw new PrestoException(LarkSheetsErrorCode.SCHEMA_ALREADY_EXISTS,
                    format("Schema '%s' already exists or created by others", name));
        }
        schemas.put(name, schema);
    }

    @Override
    public synchronized void delete(String schemaName)
    {
        String name = lower(schemaName);
        if (!schemas.containsKey(name)) {
            throw new PrestoException(LarkSheetsErrorCode.SCHEMA_NOT_EXISTS,
                    format("Schema '%s' does not exist", name));
        }
        schemas.remove(name);
    }

    @Override
    public Iterable<LarkSheetsSchema> listForUser(String user)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check existence first with a get/list call before inserting, or wrap insert in try-catch for SCHEMA_ALREADY_EXISTS and treat it as a no-op.
  2. Lowercase the schema name before creating to avoid case-variant duplicates.
  3. If the connector supports it, use IF NOT EXISTS semantics in CREATE SCHEMA.

Example fix

// before
store.insert(new LarkSheetsSchema("Sales"));

// after
try {
    store.insert(new LarkSheetsSchema("sales"));
} catch (PrestoException e) {
    if (e.getErrorCode() != LarkSheetsErrorCode.SCHEMA_ALREADY_EXISTS.toErrorCodeCode()) {
        throw e;
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean exists = store.listForUser(user) != null && streamOf(store.listForUser(user)).anyMatch(s -> s.getName().equalsIgnoreCase(name));

Type guard

boolean schemaExists(InMemorySchemaStore store, String name) { try { store.delete(name); store.insert(new LarkSheetsSchema(name)); return false; } catch (PrestoException e) { return true; } }

Try / catch

try { store.insert(schema); } catch (PrestoException e) { if (LarkSheetsErrorCode.SCHEMA_ALREADY_EXISTS.toErrorCode().getCode() == e.getErrorCode().getCode()) { /* treat as already-created: continue */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling insert(schema) when schemas already contains lower(schema.getName()). Happens on CREATE SCHEMA for a name that already exists, or two nodes/threads concurrently creating the same schema where the second caller loses the race.

Common situations: Re-running an idempotent bootstrap/provisioning script that creates schemas; concurrent CREATE SCHEMA statements racing on different Presto nodes sharing the store; case-insensitive name collision ('Sales' vs 'sales').

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/e49fa377347559f2. Report an issue: GitHub.