pocketbase/pocketbase · error

missing or unknown field type in %s

Error message

missing or unknown field type in %s

What it means

Second failure mode of fieldWithType.UnmarshalJSON: the field JSON is valid, but its "type" value does not match any registered field factory in the global Fields registry. PocketBase supports a fixed set of types; anything else (typo, custom unregistered type, or a type from a newer/older version) is rejected.

Source

Thrown at core/fields_list.go:302

type onlyFieldType struct {
	Type string `json:"type"`
}

type fieldWithType struct {
	Field
	Type string `json:"type"`
}

func (fwt *fieldWithType) UnmarshalJSON(data []byte) error {
	// extract the field type to init a blank factory
	t := &onlyFieldType{}
	if err := json.Unmarshal(data, t); err != nil {
		return fmt.Errorf("failed to unmarshal field type: %w", err)
	}

	factory, ok := Fields[t.Type]
	if !ok {
		return fmt.Errorf("missing or unknown field type in %s", data)
	}

	fwt.Type = t.Type
	fwt.Field = factory()

	// unmarshal the rest of the data into the created field
	if err := json.Unmarshal(data, fwt.Field); err != nil {
		return fmt.Errorf("failed to unmarshal field: %w", err)
	}

	return nil
}

// UnmarshalJSON implements [json.Unmarshaler] and
// loads the provided json data into the current FieldsList.
func (l *FieldsList) UnmarshalJSON(data []byte) error {
	fwts := []fieldWithType{}

View on GitHub (pinned to 5d217ddb50)

Solutions

  1. Use an exact supported type: text, number, bool, email, url, editor, date, autodate, select, file, relation, json, geoPoint.
  2. If using a custom field type from a plugin, register its factory before any collection load (usually in an app hook at startup).
  3. Re-export the collection from a PocketBase version matching the target to get correct type names.

Example fix

// before
{"type": "Text", "name": "title"} // wrong case

// after
{"type": "text", "name": "title"}
Defensive patterns

Strategy: type-guard

Validate before calling

var knownFieldTypes = map[string]bool{
    "text": true, "number": true, "bool": true, "email": true,
    "url": true, "editor": true, "date": true, "autodate": true,
    "select": true, "file": true, "relation": true, "json": true,
    "geoPoint": true,
}

Type guard

func isValidFieldType(t string) bool {
    return knownFieldTypes[t]
}

Try / catch

if err := fieldsList.UnmarshalJSON(data); err != nil {
    if strings.Contains(err.Error(), "missing or unknown field type") {
        // the message embeds the raw field JSON; point the user at its type key
    }
}

Prevention

When it happens

Trigger: A field object with type like "Text", "str", "image", or "geoPoint" (wrong case/naming), or a type introduced in a newer PocketBase being loaded by an older binary. The full raw field JSON is included in the message.

Common situations: Typos in hand-written imports; migrating collection definitions between PocketBase versions where a type was renamed (e.g. older bool/dateTime naming vs modern types); attempting to use a plugin's custom field type without registering it via core.FieldsMap/registerField before loading.

Related errors


AI-assisted analysis of pocketbase/pocketbase@5d217ddb50 (2026-08-15). Data as JSON: /api/errors/207ffd359b136f49. Report an issue: GitHub.