django/django · warning · InvalidString

%s model field maximum string length is %s, given %s charact

Error message

%s model field maximum string length is %s, given %s characters.

What it means

InvalidString (a LayerMapError subclass) raised in verify_ogr_field() when an OGR string value's length exceeds the model CharField/TextField max_length. The message reports the field name, configured max_length, and the actual character count.

Source

Thrown at django/contrib/gis/utils/layermapping.py:409

        """
        Verify if the OGR Field contents are acceptable to the model field. If
        they are, return the verified value, otherwise raise an exception.
        """
        if isinstance(ogr_field, OFTString) and isinstance(
            model_field, (models.CharField, models.TextField)
        ):
            if self.encoding and ogr_field.value is not None:
                # The encoding for OGR data sources may be specified here
                # (e.g., 'cp437' for Census Bureau boundary files).
                val = force_str(ogr_field.value, self.encoding)
            else:
                val = ogr_field.value
            if (
                model_field.max_length
                and val is not None
                and len(val) > model_field.max_length
            ):
                raise InvalidString(
                    "%s model field maximum string length is %s, given %s characters."
                    % (model_field.name, model_field.max_length, len(val))
                )
        elif isinstance(ogr_field, OFTReal) and isinstance(
            model_field, models.DecimalField
        ):
            try:
                # Creating an instance of the Decimal value to use.
                d = Decimal(str(ogr_field.value))
            except DecimalInvalidOperation:
                raise InvalidDecimal(
                    "Could not construct decimal from: %s" % ogr_field.value
                )

            # Getting the decimal value as a tuple.
            dtup = d.as_tuple()
            digits = dtup[1]
            d_idx = dtup[2]  # index where the decimal is

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Increase the model field's max_length (and run a migration) to fit the source data.
  2. Pre-truncate the source column values via ogr2ogr SQL or a custom import step.
  3. Use a TextField with no max_length for free-form strings.
  4. Run save(strict=False) to skip over-length features and log them.

Example fix

# before
class Model:
    name = models.CharField(max_length=50)  # source has 80-char names

# after
class Model:
    name = models.CharField(max_length=120)  # then makemigrations + migrate
Defensive patterns

Strategy: validation

Validate before calling

from django.contrib.gis.gdal import DataSource

def max_string_lengths(path, mapping, layer=0):
    lyr = DataSource(path)[layer]
    lengths = {}
    for k, v in mapping.items():
        if not isinstance(v, str):
            continue
        if v not in lyr.fields:
            continue
        idx = lyr.fields.index(v)
        lengths[v] = max((len(feat[idx].value or '') for feat in lyr), default=0)
    return lengths  # compare against model field max_length

Type guard

from django.db.models import CharField, TextField

def field_accepts_length(model_field, length):
    if not isinstance(model_field, (CharField, TextField)):
        return True
    return model_field.max_length is None or length <= model_field.max_length

Try / catch

from django.contrib.gis.utils.layermapping import InvalidString
lm = LayerMapping(Model, path, mapping)
lm.save(strict=False, silent=False)  # logs over-length features and continues

Prevention

When it happens

Trigger: A shapefile NAME column longer than the model's CharField(max_length=50); TextField with a max_length set receiving a long blob; source data truncated differently than expected.

Common situations: Source data fields longer than anticipated; max_length chosen for display that's too small for raw import; upstream data enrichment increasing string lengths.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/f8207cd3a0e03a94. Report an issue: GitHub.