Files
2026-07-12 10:17:17 -04:00

3.6 KiB

PocketBase Schema Patch Pattern

Use this when a PocketBase collection is missing fields needed by the frontend. The symptom is "Error saving to [collection]" with no clear error message.

Pattern

  1. Auth as superuser
  2. GET the collection schema
  3. Append missing fields to the fields array
  4. PATCH the full fields array back — NOT POST to /fields (returns 404)
#!/usr/bin/env python3
import json, urllib.request

BASE = "http://127.0.0.1:8091"
COLLECTION = "quotes"  # change as needed
EMAIL = "admin@grajmedia.duckdns.org"
PASSWORD = "RayPB2024!"

# Auth
data = json.dumps({"identity": EMAIL, "password": PASSWORD}).encode()
req = urllib.request.Request(f"{BASE}/api/collections/_superusers/auth-with-password", data=data, headers={"Content-Type": "application/json"})
token = json.loads(urllib.request.urlopen(req).read())["token"]

# Get schema
req = urllib.request.Request(f"{BASE}/api/collections/{COLLECTION}", headers={"Authorization": f"Bearer {token}"})
schema = json.loads(urllib.request.urlopen(req).read())
existing = {f["name"] for f in schema["fields"]}

# Fields to add: [(name, type), ...]
new_fields = [
    ("fieldName", "text"),
    ("otherField", "json"),
]

for name, typ in new_fields:
    if name not in existing:
        schema["fields"].append({"name": name, "type": typ, "required": False})
        print(f"Adding: {name} ({typ})")

# PATCH
req = urllib.request.Request(
    f"{BASE}/api/collections/{COLLECTION}",
    data=json.dumps({"fields": schema["fields"]}).encode(),
    headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
    method="PATCH"
)
result = json.loads(urllib.request.urlopen(req).read())
print(f"Done: {len(result['fields'])} fields total")

Common PocketBase field types

Type Use for
text strings
number integers/floats
bool booleans
json arrays, objects
date ISO 8601 datetime strings
file file uploads
select enum values (needs values array)
relation foreign keys (needs collectionId, cascadeDelete)

Silently Dropped Fields (CRITICAL)

PocketBase silently drops any field that is NOT in its collection schema. There is NO error, NO warning, NO console message. The write succeeds but the field is missing on the next read.

Symptom on read: The missing field is undefined. Code that falls back to new Date() or false silently uses the fallback — often producing wrong behavior (e.g., tasks showing as overdue with today's date because dueDateTime was dropped and new Date() was the fallback).

When adding new JS-side fields to any collection, you MUST:

  1. Add the field to the PocketBase collection schema
  2. Add any date fields to TIMESTAMP_FIELDS in pocketbase.js
  3. Restart the PocketBase container

Tasks collection (fixed June 2026)

The tasks collection was created with only 11 basic fields. These were added:

dueDateTime     text
dueTime         text
completed       bool
notes           text
isRecurring     bool
recurrenceType  text
customInterval  number
parentTaskId    text
instanceNumber  number
lastUpdated     text

SQLite direct patch (when API auth fails)

import sqlite3, json
conn = sqlite3.connect('/home/ray/docker/pocketbase/pb_data/data.db')
rows = conn.execute("SELECT id, fields FROM _collections WHERE name='tasks'").fetchall()
coll_id, fields_json = rows[0]
fields = json.loads(fields_json)
# Append missing fields, then:
conn.execute("UPDATE _collections SET fields = ? WHERE id = ?", (json.dumps(fields), coll_id))
conn.commit()
# Restart container: docker restart pocketbase