immich-app/immich · error · HTTPException
Invalid request format.
Error message
Invalid request format.
What it means
Raised as FastAPI HTTPException(422) by get_entries in machine-learning/immich_ml/main.py when parsing the 'entries' form field into a PipelineRequest fails. It catches orjson.JSONDecodeError, pydantic ValidationError, KeyError, and AttributeError — i.e. malformed JSON, missing modelName, or wrong request structure — and converts them into a uniform 422.
Source
Thrown at machine-learning/immich_ml/main.py:150
def get_entries(entries: str = Form()) -> InferenceEntries:
try:
request: PipelineRequest = orjson.loads(entries)
without_deps: list[InferenceEntry] = []
with_deps: list[InferenceEntry] = []
for task, types in request.items():
for type, entry in types.items():
parsed: InferenceEntry = {
"name": entry["modelName"],
"task": task,
"type": type,
"options": entry.get("options", {}),
}
dep = get_model_deps(parsed["name"], type, task)
(with_deps if dep else without_deps).append(parsed)
return without_deps, with_deps
except (orjson.JSONDecodeError, ValidationError, KeyError, AttributeError) as e:
log.error(f"Invalid request format: {e}")
raise HTTPException(422, "Invalid request format.")
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def root() -> ORJSONResponse:
return ORJSONResponse({"message": "Immich ML"})
@app.get("/ping")
def ping() -> PlainTextResponse:
return PlainTextResponse("pong")
@app.post("/predict", dependencies=[Depends(update_state)])
async def predict(
entries: InferenceEntries = Depends(get_entries),View on GitHub (pinned to 199723261c)
Solutions
- Ensure the Immich server and machine-learning container are on the same release version.
- Validate the entries JSON shape: top-level object keyed by task, each value keyed by type, each entry containing 'modelName'.
- If calling manually, build entries with orjson/json.dumps from a typed dict rather than hand-written JSON.
Example fix
# before
curl -F 'entries={"visual": {"search": {}}}' ... # missing modelName
# after
entries = {"visual": {"search": {"modelName": "ViT-B-32__openai"}}}
curl -F 'entries=<echo $entries' ... Defensive patterns
Strategy: validation
Validate before calling
import orjson, jsonschema
raw = orjson.loads(entries_text)
# check the {task: {type: {modelName}}} structure
for task, types in raw.items():
for type_, entry in types.items():
assert 'modelName' in entry, f'missing modelName for {task}/{type_}' Type guard
def is_pipeline_request(v) -> bool:
if not isinstance(v, dict): return False
for types in v.values():
if not isinstance(types, dict): return False
for entry in types.values():
if not isinstance(entry, dict) or 'modelName' not in entry: return False
return True Try / catch
try:
entries = json.loads(raw)
except (json.JSONDecodeError, KeyError) as e:
raise HTTPException(422, 'Invalid request format.') Prevention
- Build the entries payload with a typed pydantic model, not hand-written JSON.
- Keep the Immich server and ML service on the same version.
When it happens
Trigger: POST /predict with an 'entries' field that is not valid JSON, is missing the required 'modelName' key inside a type entry, or has a structure that does not match the {task: {type: {modelName, options}}} shape.
Common situations: Immich server and ML service version mismatch producing a different pipeline schema; a custom/old client sending the previous request format; truncated request body; manual curl with a malformed --form string.
Related errors
- Either image or text must be provided
- Task {entry['task']} of type {entry['type']} depends on outp
- Image has zero width or height
- Failed to load model '{model.model_name}'
- Invalid CLIP dimension size: ${dimSize}
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/764e47cf5db7dd48.
Report an issue: GitHub.