{"record":{"id":"c5a0fbdcbda6bc00","repo":"immich-app/immich","slug":"task-entry-task-of-type-entry-type-depen","errorCode":null,"errorMessage":"Task {entry['task']} of type {entry['type']} depends on output of {dep}","messagePattern":"Task (.+?) of type (.+?) depends on output of (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"machine-learning/immich_ml/main.py","lineNumber":199,"sourceCode":"    response = await run_inference(inputs, entries)\n    return ORJSONResponse(response)\n\n\nasync def run_inference(payload: Image | str, entries: InferenceEntries) -> InferenceResponse:\n    outputs: dict[ModelIdentity, Any] = {}\n    response: InferenceResponse = {}\n\n    async def _run_inference(entry: InferenceEntry) -> None:\n        model = await model_cache.get(\n            entry[\"name\"], entry[\"type\"], entry[\"task\"], ttl=settings.model_ttl, **entry[\"options\"]\n        )\n        inputs = [payload]\n        for dep in model.depends:\n            try:\n                inputs.append(outputs[dep])\n            except KeyError:\n                message = f\"Task {entry['task']} of type {entry['type']} depends on output of {dep}\"\n                raise HTTPException(400, message)\n        model = await load(model)\n        output = await run(model.predict, *inputs, **entry[\"options\"])\n        outputs[model.identity] = output\n        response[entry[\"task\"]] = output\n\n    without_deps, with_deps = entries\n    await asyncio.gather(*[_run_inference(entry) for entry in without_deps])\n    if with_deps:\n        await asyncio.gather(*[_run_inference(entry) for entry in with_deps])\n    if isinstance(payload, Image):\n        response[\"imageHeight\"], response[\"imageWidth\"] = payload.height, payload.width\n\n    return response\n\n\nasync def run(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:\n    if thread_pool is None:\n        return func(*args, **kwargs)","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/machine-learning/immich_ml/main.py#L181-L217","documentation":"Raised as HTTPException(400) inside run_inference when a model declares a dependency on another model's output (model.depends) but that dependency's output is not yet present in the outputs map at the time the dependent runs. This indicates the dependency task was not requested or did not run before the dependent task.","triggerScenarios":"POST /predict whose 'entries' include a task that depends on another model's output (e.g. facial recognition depending on detection, or a textual encoder paired with a visual one) but the dependency task is missing from the same request, or dependency ordering failed.","commonSituations":"Custom/cut-down request omitting the prerequisite task; model combination where depends is set but the upstream model is not loaded in the same pipeline; version mismatch where depends metadata changed.","solutions":["Include all prerequisite tasks in the same 'entries' request so their outputs populate before dependents run.","Verify the model's depends list and ensure each dependency is requested.","Use the Immich server's built-in pipeline builder rather than hand-crafting entries."],"exampleFix":"# before — only the dependent task\nentries = {\"recognition\": {\"facial-recognition\": {\"modelName\": \"buffalo_l_recognizer\"}}}\n\n# after — include the detection dependency\nentries = {\n  \"detection\":     {\"facial-recognition\": {\"modelName\": \"buffalo_l_detector\"}},\n  \"recognition\":   {\"facial-recognition\": {\"modelName\": \"buffalo_l_recognizer\"}},\n}","handlingStrategy":"validation","validationCode":"from immich_ml.models import get_model_deps\nrequired = {dep for entry in entries for dep in get_model_deps(entry['name'], entry['type'], entry['task'])}\nrequested = {(e['type'], e['task']) for e in entries}\nmissing = required - requested\nif missing: raise ValueError(f'missing dependency tasks: {missing}')","typeGuard":"def deps_satisfied(entries, outputs) -> bool:\n    for e in entries:\n        deps = get_model_class(e['name'], e['type'], e['task']).depends\n        if any(d not in outputs for d in deps): return False\n    return True","tryCatchPattern":"try:\n    await run_inference(payload, entries)\nexcept HTTPException as e:\n    if 'depends on output of' in (e.detail or ''): include_missing_dependency_tasks()\n    raise","preventionTips":["Use Immich's pipeline builder so dependencies are included automatically.","Cross-check each model's depends list when constructing custom pipelines."],"tags":["machine-learning","pipeline","model-dependency","predict","request-validation"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}