{"record":{"id":"ff87f76cfbe8c895","repo":"windmill-labs/windmill","slug":"file-resource-path-is-invalid","errorCode":null,"errorMessage":"File resource path is invalid: {}","messagePattern":"File resource path is invalid: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-worker/src/ansible_executor.rs","lineNumber":2299,"sourceCode":"            define_nsjail_mount(job_dir, &validated_path)\n                .map_err(|e| anyhow!(\"Inventory path (a.k.a. `name`) is invalid: {}\", e))?,\n        );\n\n        logs.push_str(&format!(\"\\nCreated inventory `{}`\", inventory.name));\n    }\n\n    for file_res in &r.file_resources {\n        let r =\n            get_resource_or_variable_content(client, &file_res.resource_path, job_id.to_string())\n                .await?;\n        let path = file_res.target_path.clone();\n        let validated_path =\n            write_file_at_user_defined_location(job_dir, path.as_str(), &r, file_res.mode)\n                .map_err(|e| anyhow!(\"Couldn't write text file at {}: {}\", path, e))?;\n\n        nsjail_mounts.push(\n            define_nsjail_mount(job_dir, &validated_path)\n                .map_err(|e| anyhow!(\"File resource path is invalid: {}\", e))?,\n        );\n\n        logs.push_str(&format!(\n            \"\\nCreated {} from {:?}\",\n            file_res.target_path, file_res.resource_path\n        ));\n    }\n    append_logs(job_id, w_id, logs, conn).await;\n\n    Ok(nsjail_mounts)\n}\n\nasync fn get_resource_or_variable_content(\n    client: &AuthedClient,\n    path: &ResourceOrVariablePath,\n    job_id: String,\n) -> anyhow::Result<String> {\n    Ok(match path {","sourceCodeStart":2281,"sourceCodeEnd":2317,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-worker/src/ansible_executor.rs#L2281-L2317","documentation":"After writing a file resource, the worker validates the resulting path via define_nsjail_mount because the file must be mounted into the nsjail sandbox. If the validated path cannot be expressed as a safe mount, this error is thrown and file-resource creation fails.","triggerScenarios":"create_file_resources produced a validated_path that define_nsjail_mount rejects — typically a path with symlinks, unusual characters, or one outside the mountable subtree of job_dir.","commonSituations":"Custom target paths that resolve (via symlink) outside the job directory; worker sandbox configuration changes making previously accepted paths unmountable.","solutions":["Use a simple relative target_path without symlinks or special characters in the file resource","Inspect the wrapped error detail to see which nsjail constraint failed","Ensure the worker's nsjail config permits mounting the job_dir subtree (worker setup issue)","File an issue if a previously working path stopped being accepted after a Windmill upgrade"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (fileRes.target_path.split('/').some(seg => seg.startsWith('.'))) {\n  throw new Error('Avoid dot-segments/symlink-prone names in target_path');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runJob(job);\n} catch (e) {\n  if (String(e.message).includes('File resource path is invalid')) {\n    // fix target_path or nsjail mount config\n  }\n  throw e;\n}","preventionTips":["Use plain alphanumeric target paths","Don't create symlinks inside job directories","Keep nsjail mount configuration aligned with worker job_dir layout"],"tags":["filesystem","nsjail","sandbox","ansible"],"backgroundTag":"invalid-file-path","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}