Skip to content

Moving a source markdown file crashes #88

@jhidding

Description

@jhidding

Describe the bug
Entangled can't handle a source file being moved or renamed.

To Reproduce

  1. Create a file test.md.

    ``` {.c file=test.c}
    int main() { return 0; }
    ```
  2. Start entangled watch, test.c is created.

  3. Move mv test.md not-test.md

Expected behavior

The tangled files should be updated to reference the new source location.

Bug trace

[10:14:14] INFO     2 changes detected
           WARNING  undead file `docs/src/model-alcap.md` (found in db but not on drive)
           WARNING  File `docs/src/model-alcap.md` not found.
           WARNING  File `docs/src/model-alcap.md` not found.
           WARNING  File `docs/src/model-alcap.md` not found.
           WARNING  File `docs/src/model-alcap.md` not found.
           WARNING  File `docs/src/model-alcap.md` not found.
           ERROR    docs/src/model-alcap.md
           ERROR    This error is due to an internal bug in Entangled. Please file an issue including the above stack trace and example content to reproduce the exception at
                    https://github.com/entangled/entangled.py/.
Traceback (most recent call last):
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/main.py", line 14, in cli
    main()
    ~~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/rich_click/rich_command.py", line 402, in __call__
    return super().__call__(*args, **kwargs)
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 1485, in __call__
    return self.main(*args, **kwargs)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/rich_click/rich_command.py", line 216, in main
    rv = self.invoke(ctx)
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 1873, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 1269, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 824, in invoke
    return callback(*args, **kwargs)
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/watch.py", line 47, in watch
    _watch()
    ~~~~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/watch.py", line 41, in _watch
    run_sync()
    ~~~~~~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/sync.py", line 65, in run_sync
    match sync_action(doc):
          ~~~~~~~~~~~^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/sync.py", line 22, in sync_action
    changed = set(db.changed_files(doc.context.fs))
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/io/filedb.py", line 54, in <genexpr>
    if fs[Path(p)].stat != known_stat)
       ~~^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/io/virtual.py", line 133, in __getitem__
    raise FileNotFoundError(key)
FileNotFoundError: docs/src/model-alcap.md
Traceback (most recent call last):
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/bin/entangled", line 10, in <module>
    sys.exit(cli())
             ~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/main.py", line 27, in cli
    raise e
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/main.py", line 14, in cli
    main()
    ~~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/rich_click/rich_command.py", line 402, in __call__
    return super().__call__(*args, **kwargs)
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 1485, in __call__
    return self.main(*args, **kwargs)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/rich_click/rich_command.py", line 216, in main
    rv = self.invoke(ctx)
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 1873, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 1269, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/click/core.py", line 824, in invoke
    return callback(*args, **kwargs)
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/watch.py", line 47, in watch
    _watch()
    ~~~~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/watch.py", line 41, in _watch
    run_sync()
    ~~~~~~~~^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/sync.py", line 65, in run_sync
    match sync_action(doc):
          ~~~~~~~~~~~^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/commands/sync.py", line 22, in sync_action
    changed = set(db.changed_files(doc.context.fs))
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/io/filedb.py", line 54, in <genexpr>
    if fs[Path(p)].stat != known_stat)
       ~~^^^^^^^^^
  File "/home/johannes/Code/mind-the-gap/CarboKitten/.venv/lib64/python3.14/site-packages/entangled/io/virtual.py", line 133, in __getitem__
    raise FileNotFoundError(key)
FileNotFoundError: docs/src/model-alcap.md

Desktop (please complete the following information):
Entangled version 2.4.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions