HumanSignal/label-studio · error · ValidationError

Failed to parse input file {self.file_name}: {extract_messag

Error message

Failed to parse input file {self.file_name}: {extract_message(exc)}

What it means

read_tasks wraps any exception from its format-specific readers (json/csv/tsv/txt/hypertext/generic upload) into ValidationError('Failed to parse input file <name>: <inner>'). It is a catch-all, so the actionable cause is the message appended by extract_message(exc).

Source

Thrown at label_studio/data_import/models.py:279

                tasks = self.read_tasks_list_from_txt()
            elif file_format == '.json':
                tasks = self.read_tasks_list_from_json()

            # otherwise - only one object tag should be presented in label config
            elif not self.project.one_object_in_label_config:
                raise ValidationError(
                    'Your label config has more than one data key and direct file upload supports only '
                    'one data key. To import data with multiple data keys, use a JSON or CSV file.'
                )

            # file as a single asset
            elif file_format in ('.html', '.htm', '.xml'):
                tasks = self.read_task_from_hypertext_body()
            else:
                tasks = self.read_task_from_uploaded_file()

        except Exception as exc:
            raise ValidationError('Failed to parse input file ' + self.file_name + ': ' + extract_message(exc))
        return tasks

    def read_tasks_streaming(self, file_as_tasks_list=True, batch_size=100):
        """Streaming version of read_tasks that yields tasks in batches for memory efficiency"""
        file_format = self.format

        try:
            # For JSON files, use streaming JSON parser
            if file_format == '.json':
                for batch in self.read_tasks_list_from_json_streaming(batch_size):
                    yield batch

            # For other file types, use existing methods but yield in batches
            else:
                # Use existing non-streaming methods for non-JSON files
                if file_format == '.csv' and file_as_tasks_list:
                    tasks = self.read_tasks_list_from_csv()
                elif file_format == '.tsv' and file_as_tasks_list:

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Inspect the inner message after 'Failed to parse input file ...:' and fix the root cause
  2. Verify the file extension matches the actual content and the content parses (json.tool, csv linter)
  3. Re-save the file as UTF-8; if the config error is the cause, use JSON/CSV or fix the label config

Example fix

// before: content is CSV but extension is .txt causing wrong parser
# rename data.csv.txt -> data.csv
// after: correct format/extension pairing
cp data.csv.txt data.csv && import data.csv
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-parse with the matching reader
import json, csv
text = open(path, encoding='utf8').read()
if path.endswith('.json'):
    json.loads(text)
elif path.endswith('.csv'):
    list(csv.reader(text.splitlines()))

Try / catch

try:
    tasks = fu.read_tasks()
except ValidationError as e:
    inner = str(e).split(': ', 1)[-1]  # real cause after file name
    logger.error("Import failed, root cause: %s", inner)

Prevention

When it happens

Trigger: Any parse failure inside read_tasks for the uploaded file's format: malformed JSON, bad CSV structure, encoding errors, or the multiple-data-key ValidationError raised at models.py:267.

Common situations: Wrong file extension (CSV named .txt); invalid encoding; empty file; label config mismatch raising the nested multiple-data-key error; corrupted download from storage.

Understand the failure class

Related errors


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