{"record":{"id":"d4c65d0d4825c71f","repo":"gastownhall/beads","slug":"db-createdatabaseifnotexists-w","errorCode":null,"errorMessage":"db: CreateDatabaseIfNotExists: %w","messagePattern":"db: CreateDatabaseIfNotExists: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/ddl.go","lineNumber":49,"sourceCode":"\t// classify it against their driver.\n\tCreateDatabase(ctx context.Context, database string) error\n\tUseDatabase(ctx context.Context, database string) error\n}\n\nfunc NewDDLSQLRepository(runner Runner) DDLSQLRepository {\n\treturn &ddlSQLRepository{runner: runner}\n}\n\ntype ddlSQLRepository struct {\n\trunner Runner\n}\n\nvar _ DDLSQLRepository = (*ddlSQLRepository)(nil)\n\nfunc (r *ddlSQLRepository) CreateDatabaseIfNotExists(ctx context.Context, database string) error {\n\tident, err := quoteIdentifier(database)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: CreateDatabaseIfNotExists: %w\", err)\n\t}\n\tif _, err := r.runner.ExecContext(ctx, \"CREATE DATABASE IF NOT EXISTS \"+ident); err != nil {\n\t\treturn fmt.Errorf(\"db: CreateDatabaseIfNotExists: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (r *ddlSQLRepository) CreateDatabase(ctx context.Context, database string) error {\n\tident, err := quoteIdentifier(database)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: CreateDatabase: %w\", err)\n\t}\n\tif _, err := r.runner.ExecContext(ctx, \"CREATE DATABASE \"+ident); err != nil {\n\t\treturn fmt.Errorf(\"db: CreateDatabase: %w\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/ddl.go#L31-L67","documentation":"CreateDatabaseIfNotExists wraps two distinct failures under the same prefix: an identifier validation failure from QuoteIdentifier (bad database name), and a driver failure from executing `CREATE DATABASE IF NOT EXISTS <ident>` (connection issues, insufficient privileges, server errors). Unwrap the error to distinguish which one occurred — the %w chain preserves the cause.","triggerScenarios":"Calling CreateDatabaseIfNotExists with an invalid database name (too long or illegal characters), or when the CREATE DATABASE statement fails on the server — no connection, missing CREATE privilege, or a server-side error.","commonSituations":"Bootstrap/initialization flows creating a workspace database with a misconfigured name; connecting as a user lacking CREATE privileges; database server unreachable during first run; names over 64 chars or containing hyphens.","solutions":["Unwrap the error: if it contains 'identifier too long' or 'invalid identifier', fix the database name; otherwise treat it as a server/connection problem.","Validate the name first with db.ValidateIdentifier and shorten/sanitize it.","If the cause is a driver error, check connectivity and that the DB user has CREATE privileges.","Retry after fixing the name or restoring server access."],"exampleFix":"// before\nname := os.Getenv(\"BD_DB\") // could be empty or contain hyphens\nerr := ddl.CreateDatabaseIfNotExists(ctx, name)\n// after\nname := os.Getenv(\"BD_DB\")\nif err := db.ValidateIdentifier(name); err != nil {\n    return fmt.Errorf(\"bad BD_DB %q: %w\", name, err)\n}\nerr := ddl.CreateDatabaseIfNotExists(ctx, name)","handlingStrategy":"validation","validationCode":"if err := db.ValidateIdentifier(database); err != nil {\n    return fmt.Errorf(\"cannot create database %q: %w\", database, err)\n}\nif err := conn.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"cannot create database: server unreachable: %w\", err)\n}","typeGuard":"func canCreate(name string) bool {\n    return db.ValidateIdentifier(name) == nil\n}","tryCatchPattern":"err := ddl.CreateDatabaseIfNotExists(ctx, name)\nif err != nil {\n    if vErr := db.ValidateIdentifier(name); vErr != nil {\n        return fmt.Errorf(\"bad name: %w\", vErr)\n    }\n    return fmt.Errorf(\"server rejected CREATE DATABASE: %w\", err) // privilege/connection issue\n}","preventionTips":["Always validate the name with db.ValidateIdentifier before CreateDatabaseIfNotExists to separate name errors from server errors.","Ensure the DB user has CREATE privileges in the target deployment.","Check server reachability during bootstrap before attempting DDL.","Derive database names from sanitized, bounded-length inputs."],"tags":["database","ddl","validation","privileges"],"backgroundTag":"database-create-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}