langgenius/dify · error · InvalidArgumentError
expected dict for files[0], got {type(raw_value)}
Error message
expected dict for files[0], got {type(raw_value)} What it means
Returned (HTTP 400, `invalid_param`) by PATCH on an ARRAY_FILE variable when `value` is a non-empty list but its first element is not a dict. The handler checks `raw_value[0]` to fail fast before calling `build_from_mappings`, which would otherwise crash on a non-mapping element. Note the error message string still prints `type(raw_value)` (the list) rather than the element type — a known cosmetic bug.
Source
Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_draft_variable.py:260
if new_name is None and raw_value is None:
return variable
new_value = None
if raw_value is not None:
match variable.value_type:
case SegmentType.FILE:
if not isinstance(raw_value, dict):
raise InvalidArgumentError(description=f"expected dict for file, got {type(raw_value)}")
raw_value = build_from_mapping(
mapping=raw_value,
tenant_id=pipeline.tenant_id,
access_controller=_file_access_controller,
)
case SegmentType.ARRAY_FILE:
if not isinstance(raw_value, list):
raise InvalidArgumentError(description=f"expected list for files, got {type(raw_value)}")
if len(raw_value) > 0 and not isinstance(raw_value[0], dict):
raise InvalidArgumentError(description=f"expected dict for files[0], got {type(raw_value)}")
raw_value = build_from_mappings(
mappings=raw_value,
tenant_id=pipeline.tenant_id,
access_controller=_file_access_controller,
)
case _:
pass
new_value = build_segment_with_type(variable.value_type, raw_value)
draft_var_srv.update_variable(variable, name=new_name, value=new_value)
db.session.commit()
return variable
@console_ns.response(204, "Variable deleted successfully")
@_api_prerequisite
def delete(self, _current_user: Account, pipeline: Pipeline, variable_id: UUID):
draft_var_srv = WorkflowDraftVariableService(
session=db.session(),
)View on GitHub (pinned to ef8544b173)
Solutions
- Ensure every element of the `value` array is a file-mapping object.
- Map each id to its object before send: `value: ids.map(id => ({ type, transfer_method, upload_file_id: id }))`.
- Reject mixed-type arrays client-side before PATCH.
- When the list is non-empty, validate `Array.isArray(value) && value.every(v => v && typeof v === 'object')`.
Example fix
// before
{ "value": [ "daded54f-72c7-4f8e-9d18-9b0abdd9f190" ] }
// after
{ "value": [ { "type": "image", "transfer_method": "local_file", "upload_file_id": "daded54f-72c7-4f8e-9d18-9b0abdd9f190" } ] } Defensive patterns
Strategy: type-guard
Validate before calling
function asFileMappingArray(v: unknown): object[] {
if (!Array.isArray(v)) throw new Error('value must be array')
if (v.length > 0 && (typeof v[0] !== 'object' || v[0] === null || Array.isArray(v[0]))) {
throw new Error('array elements must be file mapping objects')
}
return v as object[]
} Type guard
function isFileMappingArray(v: unknown): v is object[] {
return Array.isArray(v) && (v.length === 0 || (typeof v[0] === 'object' && v[0] !== null && !Array.isArray(v[0])))
} Try / catch
try {
await patch(...)
} catch (e) {
if (e.code === 'invalid_param' && /expected dict for files\[0\]/.test(e.message)) {
// map each element id -> mapping object, retry once
} else throw e
} Prevention
- Map every selected file id to its full mapping object before sending.
- Reject arrays whose first element is not a plain object.
- Run `value.every(v => v && typeof v === 'object')` client-side.
When it happens
Trigger: Sending `"value": ["<upload_file_id>"]` (list of strings) instead of a list of objects; mixing object and string elements with a string at index 0; passing a list parsed from a flat CSV.
Common situations: Frontend mapping over selected files and emitting only their ids. API gateway that flattens nested objects. Test fixtures building the array from string columns.
Related errors
- expected dict for file, got {type(raw_value)}
- expected list for files, got {type(raw_value)}
- Draft workflow not found, pipeline_id={pipeline.id}
- draft_workflow_not_exist
- draft_workflow_not_exist
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/65b9eb37919f222d.
Report an issue: GitHub.