litedb-org/LiteDB · error · LiteException

0

0

Error message

Pragma COLLATION is read only. Use Rebuild options.

What it means

Thrown when a user attempts to change the COLLATION pragma at runtime via Pragma('COLLATION', value) or the equivalent SQL. Collation is persisted into the database header page at creation time and drives every index comparison; changing it in-place would invalidate all existing B-tree orderings. The engine marks its Validate callback as an unconditional throw, so any validated set is rejected.

Source

Thrown at LiteDB/Engine/EnginePragmas.cs:92

            _pragmas = new Dictionary<string, Pragma>(StringComparer.OrdinalIgnoreCase)
            {
                [Engine.Pragmas.USER_VERSION] = new Pragma
                {
                    Name = Engine.Pragmas.USER_VERSION,
                    Get = () => this.UserVersion,
                    Set = (v) => this.UserVersion = v.AsInt32,
                    Read = (b) => this.UserVersion = b.ReadInt32(P_USER_VERSION),
                    Validate = (v, h) => { },
                    Write = (b) => b.Write(this.UserVersion, P_USER_VERSION)
                },
                [Engine.Pragmas.COLLATION] = new Pragma
                {
                    Name = Engine.Pragmas.COLLATION,
                    Get = () => this.Collation.ToString(),
                    Set = (v) => this.Collation = new Collation(v.AsString),
                    Read = (b) => this.Collation = new Collation(b.ReadInt32(P_COLLATION_LCID), (CompareOptions)b.ReadInt32(P_COLLATION_SORT)),
                    Validate = (v, h) => { throw new LiteException(0, "Pragma COLLATION is read only. Use Rebuild options."); },
                    Write = (b) =>
                    {
                        b.Write(this.Collation.LCID, P_COLLATION_LCID);
                        b.Write((int)this.Collation.SortOptions, P_COLLATION_SORT);
                    }
                },
                [Engine.Pragmas.TIMEOUT] = new Pragma
                {
                    Name = Engine.Pragmas.TIMEOUT,
                    Get = () => (int)this.Timeout.TotalSeconds,
                    Set = (v) => this.Timeout = TimeSpan.FromSeconds(v.AsInt32),
                    Read = (b) => this.Timeout = TimeSpan.FromSeconds(b.ReadInt32(P_TIMEOUT)),
                    Validate = (v, h) => { if (v <= 0) throw new LiteException(0, "Pragma TIMEOUT must be greater than zero"); },
                    Write = (b) => b.Write((int)this.Timeout.TotalSeconds, P_TIMEOUT)
                },
                [Engine.Pragmas.LIMIT_SIZE] = new Pragma
                {
                    Name = Engine.Pragmas.LIMIT_SIZE,

View on GitHub (pinned to f906a5f850)

Solutions

  1. Set collation at database creation time via EngineSettings.Collation or the connection string Collation parameter.
  2. To change collation on an existing database, use the Rebuild API with a new collation (db.Rebuild(options => options.Collation = new Collation(...))).
  3. Remove COLLATION from any generic pragma-application loop.
  4. If you only need culture-aware comparison for a query, transform/sort in application code rather than changing the DB collation.

Example fix

// before — tries to set at runtime
db.Pragma("COLLATION", "en-US/None"); // throws

// after — set at creation
var db = new LiteDatabase("connection string { collation=en-US/None }");
// or rebuild to change later
db.Rebuild(c => c.Collation = new Collation("en-US/None"));
Defensive patterns

Strategy: validation

Validate before calling

// Never set COLLATION at runtime; set it at creation or via Rebuild.
public void ApplyPragma(LiteDatabase db, string name, BsonValue value)
{
    if (string.Equals(name, LiteDB.Engine.Pragmas.COLLATION, StringComparison.OrdinalIgnoreCase))
    {
        // skip — read-only pragma
        return;
    }
    db.Pragma(name, value);
}

Type guard

static bool IsReadOnlyPragma(string name) =>
    string.Equals(name, LiteDB.Engine.Pragmas.COLLATION, StringComparison.OrdinalIgnoreCase);

Try / catch

try
{
    db.Pragma(LiteDB.Engine.Pragmas.COLLATION, collationString);
}
catch (LiteException ex) when (ex.Message.Contains("COLLATION is read only"))
{
    // Use Rebuild instead:
    // db.Rebuild(c => c.Collation = new Collation(collationString));
    throw new InvalidOperationException("Collation is immutable post-creation. Use Rebuild to change it.", ex);
}

Prevention

When it happens

Trigger: Executing PRAGMA COLLATION = '...' via SQL or calling engine.Pragma(Pragma.COLLATION, value) after the database has been created. The Validate delegate runs during Set(name, value, validate: true).

Common situations: Migrating a database to a new locale without realizing collation is immutable post-creation; scripting a generic 'apply pragmas' routine that blindly sets all pragmas; attempting culture-specific sorting on an existing DB.

Related errors


AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13). Data as JSON: /api/errors/958bbd67d7148b78. Report an issue: GitHub.