{"record":{"id":"948ad52ca5f50141","repo":"hashicorp/nomad","slug":"error-moving-task-q-local-dir-w","errorCode":null,"errorMessage":"error moving task %q local dir: %w","messagePattern":"error moving task %q local dir: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocdir/alloc_dir.go","lineNumber":313,"sourceCode":"\t\t}\n\t}\n\n\t// Move the task directories\n\tfor _, task := range tasks {\n\t\totherTaskDir := filepath.Join(other.AllocDirPath(), task.Name)\n\t\totherTaskLocal := filepath.Join(otherTaskDir, TaskLocal)\n\n\t\tfileInfo, err := os.Stat(otherTaskLocal)\n\t\tif fileInfo != nil && err == nil {\n\t\t\t// TaskDirs haven't been built yet, so create it\n\t\t\tnewTaskDir := filepath.Join(a.AllocDir, task.Name)\n\t\t\tif err := os.MkdirAll(newTaskDir, fileMode777); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error creating task %q dir: %w\", task.Name, err)\n\t\t\t}\n\t\t\tlocalDir := filepath.Join(newTaskDir, TaskLocal)\n\t\t\tos.Remove(localDir) // remove an empty local dir if it exists\n\t\t\tif err := os.Rename(otherTaskLocal, localDir); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error moving task %q local dir: %w\", task.Name, err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Destroy tears down previously build directory structure.\nfunc (a *AllocDir) Destroy() error {\n\t// Unmount all mounted shared alloc dirs.\n\tmErr := new(multierror.Error)\n\tif err := a.UnmountAll(); err != nil {\n\t\tmErr = multierror.Append(mErr, err)\n\t}\n\n\tif err := os.RemoveAll(a.AllocDir); err != nil {\n\t\tmErr = multierror.Append(mErr, fmt.Errorf(\"failed to remove alloc dir %q: %w\", a.AllocDir, err))\n\t}","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocdir/alloc_dir.go#L295-L331","documentation":"After creating the new task directory, Move renames the previous allocation's task-local directory into it via os.Rename. Failure of that rename (cross-device, permissions, destination conflict) yields 'error moving task %q local dir'. This wraps the raw OS error so the task name is identified.","triggerScenarios":"os.Rename(otherTaskLocal, localDir) fails — source and target on different devices, the pre-removed localDir path recreated concurrently, or permission denial on either side.","commonSituations":"Same cross-device mount issues as data-dir moves; lingering handles on the local dir (task still running) preventing atomic rename on some systems; race with node GC removing the old alloc dir.","solutions":["Ensure both alloc dirs share a filesystem","Stop the old task/allocation before migration so no process holds the local dir","Check permissions on old task local dir and new task dir","Retry if racing with GC; coordinate GC to not delete migrating allocations"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := allocDir.Move(other, tasks); err != nil && strings.Contains(err.Error(), \"error moving task\") {\n  // ensure old alloc stopped and same-filesystem, then retry\n}","preventionTips":["Stop the old allocation before migrating its local dirs","Keep old/new alloc dirs on the same device","Coordinate GC so it never deletes allocations mid-migration"],"tags":["filesystem","rename","allocation-migration"],"backgroundTag":"cross-device-rename","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}