HumanSignal/label-studio · warning · NotFound

"form_layout.yml" is not found for {self.__class__.__name__}

Error message

"form_layout.yml" is not found for {self.__class__.__name__}

What it means

StorageFormLayoutAPI.get locates a form_layout.yml next to the storage class's module file; if the YAML file does not exist for that storage backend, it raises NotFound naming the class. The endpoint serves the dynamic form definition used by the UI to render storage connection forms.

Source

Thrown at label_studio/io_storages/api.py:244

                    break

            return Response({'files': files})
        except Exception as exc:
            logger.exception('Error listing storage files: %s', exc)
            raise ValidationError('Failed to list storage files')


@extend_schema(exclude=True)
class StorageFormLayoutAPI(generics.RetrieveAPIView):
    permission_required = all_permissions.storages_change
    parser_classes = (JSONParser, FormParser, MultiPartParser)
    storage_type = None

    @extend_schema(exclude=True)
    def get(self, request, *args, **kwargs):
        form_layout_file = os.path.join(os.path.dirname(inspect.getfile(self.__class__)), 'form_layout.yml')
        if not os.path.exists(form_layout_file):
            raise NotFound(f'"form_layout.yml" is not found for {self.__class__.__name__}')

        form_layout = read_yaml(form_layout_file)
        form_layout = self.post_process_form(form_layout)
        return Response(form_layout[self.storage_type])

    def post_process_form(self, form_layout):
        return form_layout


class ImportStorageValidateAPI(StorageValidateAPI):
    serializer_class = ImportStorageSerializer


class ExportStorageValidateAPI(StorageValidateAPI):
    serializer_class = ExportStorageSerializer


class ImportStorageFormLayoutAPI(StorageFormLayoutAPI):

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Add a form_layout.yml to the storage backend package directory
  2. If packaging a custom storage, include YAML files in package_data/MANIFEST.in
  3. Verify storage_type matches a supported backend that ships form_layout.yml
  4. Reinstall the label-storage package from a complete source checkout

Example fix

// before
my_storages/ftp/  # contains models.py, serializers.py but no form_layout.yml → 404
// after
my_storages/ftp/form_layout.yml  # added, listing import/export form fields → 200
Defensive patterns

Strategy: fallback

Validate before calling

# for custom storage packages, ensure the file ships before registering the endpoint
import inspect, os
mod_dir = os.path.dirname(inspect.getfile(MyStorageAPI.serializer_class.Meta.model))
assert os.path.exists(os.path.join(mod_dir, "form_layout.yml")), "form_layout.yml missing"

Try / catch

try:
    resp = requests.get(f"{LS_URL}/api/storages/form-layouts/", params={"type": storage_type}, headers=headers)
    resp.raise_for_status()
except requests.HTTPError as e:
    if resp.status_code == 404:
        layout = DEFAULT_FORM_LAYOUT  # fall back to a locally-defined schema

Prevention

When it happens

Trigger: GET /api/storages/form-layouts?storage_type=... for a storage backend whose package directory lacks form_layout.yml (custom or third-party storage type without the file, or source distribution missing the data file).

Common situations: Custom storage plugin copied from a template without adding form_layout.yml; pip package built without including the YAML (missing package_data in setup.py); pointing storage_type at a backend that ships no form layout.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/79780584696e48f9. Report an issue: GitHub.