{"record":{"id":"01125544ab94193a","repo":"hashicorp/nomad","slug":"work-dir-must-be-absolute-but-got-relative-path-q","errorCode":null,"errorMessage":"work_dir must be absolute but got relative path %q","messagePattern":"work_dir must be absolute but got relative path %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/exec/driver.go","lineNumber":244,"sourceCode":"\tswitch tc.ModeIPC {\n\tcase \"\", executor.IsolationModePrivate, executor.IsolationModeHost:\n\tdefault:\n\t\treturn fmt.Errorf(\"ipc_mode must be %q or %q, got %q\", executor.IsolationModePrivate, executor.IsolationModeHost, tc.ModeIPC)\n\t}\n\n\tsupported := capabilities.Supported()\n\tbadAdds := supported.Difference(capabilities.New(tc.CapAdd))\n\tif !badAdds.Empty() {\n\t\treturn fmt.Errorf(\"cap_add configured with capabilities not supported by system: %s\", badAdds)\n\t}\n\n\tbadDrops := supported.Difference(capabilities.New(tc.CapDrop))\n\tif !badDrops.Empty() {\n\t\treturn fmt.Errorf(\"cap_drop configured with capabilities not supported by system: %s\", badDrops)\n\t}\n\n\tif tc.WorkDir != \"\" && !filepath.IsAbs(tc.WorkDir) {\n\t\treturn fmt.Errorf(\"work_dir must be absolute but got relative path %q\", tc.WorkDir)\n\t}\n\n\treturn nil\n}\n\n// TaskState is the state which is encoded in the handle returned in\n// StartTask. This information is needed to rebuild the task state and handler\n// during recovery.\ntype TaskState struct {\n\tReattachConfig *pstructs.ReattachConfig\n\tTaskConfig     *drivers.TaskConfig\n\tPid            int\n\tStartedAt      time.Time\n}\n\ntype UserIDValidator interface {\n\tHasValidIDs(userName string) error\n}","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/exec/driver.go#L226-L262","documentation":"If the task sets work_dir, validate() requires it to be an absolute path (filepath.IsAbs). A relative work_dir would be ambiguous inside the chroot/isolated filesystem, so the task is rejected with this message.","triggerScenarios":"Task config work_dir = \"app/bin\" or similar relative path (any value that fails filepath.IsAbs while non-empty).","commonSituations":"Assuming work_dir is relative to the task dir like Docker WORKDIR conventions; porting configs where leading \"/\" was lost; templating errors producing relative paths.","solutions":["Prefix work_dir with \"/\" to make it absolute (paths are interpreted within the task's chroot)","Remove work_dir to use the default","Fix templates that emit relative paths"],"exampleFix":"// before\nconfig {\n  work_dir = \"opt/app\"\n}\n// after\nconfig {\n  work_dir = \"/opt/app\"\n}","handlingStrategy":"validation","validationCode":"if tc.WorkDir != \"\" && !filepath.IsAbs(tc.WorkDir) {\n  return fmt.Errorf(\"work_dir must be absolute: %q\", tc.WorkDir)\n}","typeGuard":"func isAbsWorkDir(p string) bool {\n  return p == \"\" || filepath.IsAbs(p)\n}","tryCatchPattern":"if err := task.Validate(); err != nil {\n  if strings.Contains(err.Error(), \"work_dir\") {\n    cfg.WorkDir = \"/\" + cfg.WorkDir\n    err = task.Validate()\n  }\n  return err\n}","preventionTips":["Always start work_dir with \"/\" in job specs","Remember paths are relative to the task chroot, not the host","Add schema linting to job templating pipelines"],"tags":["nomad","exec-driver","task-config","validation"],"backgroundTag":"invalid-driver-config","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"}