Ansible expected paths error I have a webserver playbook containing the following:

- hosts: webserver
  become: true
  roles:
    - apache2
    - { role: demo_app, db_user: demo, db_pass: demo, db_name: demo }


My folder structure is 

.
├── ansible
│   ├── ansible
│   ├── ansible.cfg
│   ├── ansible.pub
│   ├── dev
│   ├── docker-compose.yml
│   ├── Docker.zip
│   ├── env
│   │   ├── ansible
│   │   ├── ansible.pub
│   │   ├── Dockerfile
│   │   ├── init-fake.conf
│   │   ├── ssh_config
│   │   └── ssh_host_config
│   ├── playbooks
│   │   ├── database.yml
│   │   ├── hostname.yml
│   │   └── loadbalancer.yml
│   ├── startup.sh
│   └── temp
│       ├── ansible
│       ├── ansible.cfg
│       ├── ansible.pub
│       ├── dev
│       ├── docker-compose.yml
│       └── Docker.zip
├── ansible.cfg
├── ansible.pub
├── control.yml
├── database.yml
├── demo
│   └── demo.conf
├── dev
├── docker-compose.yml
├── Docker.zip
├── env
│   ├── ansible
│   ├── ansible.pub
│   ├── Dockerfile
│   ├── init-fake.conf
│   ├── ssh_config
│   └── ssh_host_config
├── loadbalancer.yml
├── main.yml
├── playbooks
│   ├── hostname.yml
│   ├── stack_restart.yml
│   └── stack_status.yml
├── roles
│   ├── apache2
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── README.md
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   ├── tests
│   │   │   ├── inventory
│   │   │   └── test.yml
│   │   └── vars
│   │       └── main.yml
│   ├── control
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── README.md
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   ├── tests
│   │   │   ├── inventory
│   │   │   └── test.yml
│   │   └── vars
│   │       └── main.yml
│   ├── demo_app
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   │   └── app
│   │   │       ├── demo.py
│   │   │       └── requirements.txt
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── README.md
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   │   └── demo.wsgi.j2
│   │   ├── tests
│   │   │   ├── inventory
│   │   │   └── test.yml
│   │   └── vars
│   │       └── main.yml
│   ├── mysql
│   │   ├── defaults
│   │   ├── files
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── README.md
│   │   ├── tasks
│   │   ├── templates
│   │   ├── tests
│   │   │   ├── inventory
│   │   │   └── test.yml
│   │   └── vars
│   │       └── main.yml
│   └── nginx
│       ├── defaults
│       ├── files
│       ├── handlers
│       │   └── main.yml
│       ├── meta
│       │   └── main.yml
│       ├── README.md
│       ├── tasks
│       ├── templates
│       │   └── nginx.conf.j2
│       ├── tests
│       │   ├── inventory
│       │   └── test.yml
│       └── vars
│           └── main.yml
├── site.yml
├── startup.sh
├── templates
├── webserver.retry
└── webserver.yml


Ansible version is 2.2.1. I'm getting the following error when trying to run ansible-playbook webserver.yml

TASK [demo_app : copy demo app source] *****************************************
fatal: [app01]: FAILED! =&gt; {"changed": false, "failed": true, "msg": "Unable to find 'demo/app/' in expected paths."}
fatal: [app02]: FAILED! =&gt; {"changed": false, "failed": true, "msg": "Unable to find 'demo/app/' in expected paths."}
    to retry, use: --limit @/work/webserver.retry

PLAY RECAP *********************************************************************
app01                      : ok=6    changed=0    unreachable=0    failed=1   
app02                      : ok=6    changed=0    unreachable=0    failed=1   


The relevant task is:

- name: copy demo app source
  copy: src=demo/app/ dest=/var/www/demo mode=0755
  notify: restart apache2


I've tried altering the above copy src to /demo_app and also src=demo_app/files/app but this didnt help.
The task which fails is:

- name: copy demo app source
  copy: src=demo/app/ dest=/var/www/demo mode=0755
  notify: restart apache2


If you have a look at your folder structure and more specifically the demo_app role, you have:

│   ├── demo_app
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   │   └── app
│   │   │       ├── demo.py
│   │   │       └── requirements.txt
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── README.md
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   │   └── demo.wsgi.j2
│   │   ├── tests
│   │   │   ├── inventory
│   │   │   └── test.yml
│   │   └── vars
│   │       └── main.yml


The copy task will look for the src in demo_app/files/. So, either change your task to:

- name: copy demo app source
  copy: src=app dest=/var/www/demo mode=0755
  notify: restart apache2


Or create a demo directory in demo_app/files/ and place the app directory in it (like demo_app/files/demo/app/).

Setting an absolute path to the directory in the task will also work, but don't think it's an elegant solution.