{"record":{"id":"d44cc59fdebbf902","repo":"EpicGames/lore","slug":"task-failed","errorCode":null,"errorMessage":"task failed","messagePattern":"task failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lore-revision/src/metadata/set.rs","lineNumber":437,"sourceCode":"\n        lore_spawn!(tasks, {\n            async move {\n                set_file_task(\n                    repository,\n                    state,\n                    &path,\n                    &keys_vec,\n                    &values_vec,\n                    &formats,\n                    events,\n                )\n                .await\n            }\n        });\n\n        while tasks.len() > MAX_TASK_COUNT {\n            if let Some(result) = tasks.join_next().await {\n                failure = failure.or(result.internal(\"task failed\").err());\n            }\n        }\n\n        if failure.is_some() {\n            break;\n        }\n\n        offset += count;\n    }\n\n    while let Some(result) = tasks.join_next().await {\n        failure = failure.or(result.internal(\"task failed\").err());\n    }\n\n    if let Some(err) = failure {\n        return Err(err.into());\n    }\n","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/EpicGames/lore/blob/074eb0b0d1194c997d7cf28b55519e3e197b3e23/lore-revision/src/metadata/set.rs#L419-L455","documentation":"In `set_file` (lore-revision metadata), per-path `set_file_task` futures run in a bounded JoinSet (max 1000 concurrent). When draining tasks to stay under MAX_TASK_COUNT, `result.internal(\"task failed\")` wraps any task failure — a JoinError from a panicked/aborted task, or the task's own SetError — into a SetError labeled \"task failed\".","triggerScenarios":"While more than 1000 tasks are queued, one of the joined `set_file_task` futures returns Err (e.g. it failed to load/serialize state, write metadata for a path) or its tokio task panicked and was joined as a JoinError.","commonSituations":"Bulk metadata sets over >1000 paths where one path's state cannot be read/written (corrupt repository, missing state files); a task panicking due to an internal bug; repository storage errors under concurrent load.","solutions":["Fix the underlying per-path error: it is reported via the `.or()` merge only if it is the first failure — check the Err payload for the real cause","Validate repository state files are readable and not corrupt before bulk set operations","Retry the operation on a smaller batch of paths to isolate the failing path","If caused by a panic in set_file_task, reproduce with a single path and fix the task code"],"exampleFix":"// before\nfailure = failure.or(result.internal(\"task failed\").err());\n// after\nfailure = failure.or(match result {\n    Ok(Err(e)) => Some(e),\n    Ok(Ok(())) => None,\n    Err(join_err) => SetError::internal(format!(\"metadata task panicked: {join_err}\")).err(),\n});","handlingStrategy":"try-catch","validationCode":"// Pre-validate inputs before spawning tasks\nassert_eq!(paths.len(), entries.len(), \"paths/entries length mismatch\");\nassert_eq!(entries.iter().sum::<u32>() as usize, keys.len());","typeGuard":null,"tryCatchPattern":"match tasks.join_next().await {\n    Some(Ok(Ok(()))) => {}\n    Some(Ok(Err(e))) => failure = failure.or(Some(e)),\n    Some(Err(join_err)) => failure = failure.or(Some(SetError::internal(join_err.to_string()))),\n    None => {}\n}","preventionTips":["Batch very large metadata sets to keep concurrency bounded and failures isolated","Ensure repository state files are intact before bulk operations","Make per-task errors carry the path so failures are attributable"],"tags":["rust","tokio","concurrency","task-join","metadata"],"backgroundTag":"internal-invariant-violation","analyzedSha":"074eb0b0d1194c997d7cf28b55519e3e197b3e23","analyzedAt":"2026-09-13T09:00:57.509Z","contentChangedAt":"2026-09-13T09:00:57.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}