# Buggy code
def edit_file(self, filename):
    vault_id_used = None
    vault_secret_used = None
    # follow the symlink
    filename = self._real_path(filename)

    b_vaulttext = self.read_data(filename)

    # vault or yaml files are always utf8
    vaulttext = to_text(b_vaulttext)

    try:
        # vaulttext gets converted back to bytes, but alas
        # TODO: return the vault_id that worked?
        plaintext, vault_id_used, vault_secret_used = (
            self.vault.decrypt_and_get_vault_id(vaulttext)
        )
    except AnsibleError as e:
        raise AnsibleError("%s for %s" % (to_bytes(e), to_bytes(filename)))

    # Figure out the vault id from the file, to select the right secret to re-encrypt it
    # (duplicates parts of decrypt, but alas...)
    dummy, dummy, cipher_name, vault_id = parse_vaulttext_envelope(
        b_vaulttext, filename=filename
    )

    # vault id here may not be the vault id actually used for decrypting
    # as when the edited file has no vault-id but is decrypted by non-default id in secrets
    # (vault_id=default, while a different vault-id decrypted)

    # Keep the same vault-id (and version) as in the header
    if cipher_name not in CIPHER_WRITE_WHITELIST:
        # we want to get rid of files encrypted with the AES cipher
        self._edit_file_helper(
            filename,
            vault_secret_used,
            existing_data=plaintext,
            force_save=True,
            vault_id=vault_id,
        )
    else:
        self._edit_file_helper(
            filename,
            vault_secret_used,
            existing_data=plaintext,
            force_save=False,
            vault_id=vault_id,
        )


# Traceback (OSError)
ansible-vault 2.6.3
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/the-noob/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible-vault
python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
Using /etc/ansible/ansible.cfg as config file
Vault password:
ERROR! Unexpected Exception, this is probably a bug: [Errno 2] No such file or directory
the full traceback was:

Traceback (most recent call last):
File "/usr/bin/ansible-vault", line 118, in <module>
exit_code = cli.run()
File "/usr/lib/python2.7/dist-packages/ansible/cli/vault.py", line 255, in run
self.execute()
File "/usr/lib/python2.7/dist-packages/ansible/cli/__init__.py", line 155, in execute
fn()
File "/usr/lib/python2.7/dist-packages/ansible/cli/vault.py", line 446, in execute_edit
self.editor.edit_file(f)
File "/usr/lib/python2.7/dist-packages/ansible/parsing/vault/__init__.py", line 975, in edit_file
force_save=False, vault_id=vault_id)
File "/usr/lib/python2.7/dist-packages/ansible/parsing/vault/__init__.py", line 864, in _edit_file_helper
subprocess.call(self._editor_shell_command(tmp_path))
File "/usr/lib/python2.7/subprocess.py", line 523, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

# Fixed code
def edit_file(self, filename):
    vault_id_used = None
    vault_secret_used = None
    # follow the symlink
    filename = self._real_path(filename)

    b_vaulttext = self.read_data(filename)

    # vault or yaml files are always utf8
    vaulttext = to_text(b_vaulttext)

    try:
        # vaulttext gets converted back to bytes, but alas
        # TODO: return the vault_id that worked?
        plaintext, vault_id_used, vault_secret_used = (
            self.vault.decrypt_and_get_vault_id(vaulttext)
        )
    except AnsibleError as e:
        raise AnsibleError("%s for %s" % (to_native(e), to_native(filename)))

    # Figure out the vault id from the file, to select the right secret to re-encrypt it
    # (duplicates parts of decrypt, but alas...)
    dummy, dummy, cipher_name, vault_id = parse_vaulttext_envelope(
        b_vaulttext, filename=filename
    )

    # vault id here may not be the vault id actually used for decrypting
    # as when the edited file has no vault-id but is decrypted by non-default id in secrets
    # (vault_id=default, while a different vault-id decrypted)

    # Keep the same vault-id (and version) as in the header
    if cipher_name not in CIPHER_WRITE_WHITELIST:
        # we want to get rid of files encrypted with the AES cipher
        self._edit_file_helper(
            filename,
            vault_secret_used,
            existing_data=plaintext,
            force_save=True,
            vault_id=vault_id,
        )
    else:
        self._edit_file_helper(
            filename,
            vault_secret_used,
            existing_data=plaintext,
            force_save=False,
            vault_id=vault_id,
        )