diff --git a/newsfragments/552.bugfix.rst b/newsfragments/552.bugfix.rst
new file mode 100644
index 00000000..8239edcf
--- /dev/null
+++ b/newsfragments/552.bugfix.rst
@@ -0,0 +1,1 @@
+When a Trio task makes improper use of a non-Trio async library, Trio now causes an exception to be raised within the task at the point of the error, rather than abandoning the task and raising an error in its parent. This improves debuggability and resolves the `TrioInternalError` that would sometimes result from the latter strategy.
diff --git a/trio/_core/_run.py b/trio/_core/_run.py
index 96da9262..d662d0eb 100644
--- a/trio/_core/_run.py
+++ b/trio/_core/_run.py
@@ -980,10 +980,17 @@ class Task:
     _counter = attr.ib(init=False, factory=itertools.count().__next__)
 
     # Invariant:
-    # - for unscheduled tasks, _next_send is None
-    # - for scheduled tasks, _next_send is an Outcome object,
-    #   and custom_sleep_data is None
+    # - for unscheduled tasks, _next_send_fn and _next_send are both None
+    # - for scheduled tasks, _next_send_fn(_next_send) resumes the task;
+    #   usually _next_send_fn is self.coro.send and _next_send is an
+    #   Outcome. When recovering from a foreign await, _next_send_fn is
+    #   self.coro.throw and _next_send is an exception. _next_send_fn
+    #   will effectively be at the top of every task's call stack, so
+    #   it should be written in C if you don't want to pollute Trio
+    #   tracebacks with extraneous frames.
+    # - for scheduled tasks, custom_sleep_data is None
     # Tasks start out unscheduled.
+    _next_send_fn = attr.ib(default=None)
     _next_send = attr.ib(default=None)
     _abort_func = attr.ib(default=None)
     custom_sleep_data = attr.ib(default=None)
@@ -1215,7 +1222,8 @@ class Runner:
             next_send = Value(None)
 
         assert task._runner is self
-        assert task._next_send is None
+        assert task._next_send_fn is None
+        task._next_send_fn = task.coro.send
         task._next_send = next_send
         task._abort_func = None
         task.custom_sleep_data = None
@@ -1887,8 +1895,9 @@ def run_impl(runner, async_fn, args):
             if runner.instruments:
                 runner.instrument("before_task_step", task)
 
+            next_send_fn = task._next_send_fn
             next_send = task._next_send
-            task._next_send = None
+            task._next_send_fn = task._next_send = None
             final_outcome = None
             try:
                 # We used to unwrap the Outcome object here and send/throw its
@@ -1898,7 +1907,7 @@ def run_impl(runner, async_fn, args):
                 #   https://bugs.python.org/issue29590
                 # So now we send in the Outcome object and unwrap it on the
                 # other side.
-                msg = task.context.run(task.coro.send, next_send)
+                msg = task.context.run(next_send_fn, next_send)
             except StopIteration as stop_iteration:
                 final_outcome = Value(stop_iteration.value)
             except BaseException as task_exc:
@@ -1938,16 +1947,12 @@ def run_impl(runner, async_fn, args):
                         "other framework like asyncio? That won't work "
                         "without some kind of compatibility shim.".format(msg)
                     )
-                    # How can we resume this task? It's blocked in code we
-                    # don't control, waiting for some message that we know
-                    # nothing about. We *could* try using coro.throw(...) to
-                    # blast an exception in and hope that it propagates out,
-                    # but (a) that's complicated because we aren't set up to
-                    # resume a task via .throw(), and (b) even if we did,
-                    # there's no guarantee that the foreign code will respond
-                    # the way we're hoping. So instead we abandon this task
-                    # and propagate the exception into the task's spawner.
-                    runner.task_exited(task, Error(exc))
+                    # The foreign library probably doesn't adhere to our
+                    # protocol of unwrapping whatever outcome gets sent in.
+                    # Instead, we'll arrange to throw `exc` in directly,
+                    # which works for at least asyncio and curio.
+                    runner.reschedule(task, exc)
+                    task._next_send_fn = task.coro.throw
 
             if runner.instruments:
                 runner.instrument("after_task_step", task)

Our code for recovering after a "foreign await" needs to be reworked
Just doing some testing to see if I can use `dask.distributed` with `trio` & `trio_asyncio` but have fallen at the first hurdle and hit a `TrioInternalError`:

```python
import asyncio
import trio
import trio_asyncio
from dask.distributed import Client


async def f():
    async with trio_asyncio.open_loop() as loop:
        client = await Client(asynchronous=True)
        future = client.submit(lambda x: x + 1, 10)
        return await future

trio.run(f)
```
```python-traceback
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
C:\Miniconda3\lib\site-packages\trio\_core\_run.py in run(async_fn, clock, instruments, restrict_keyboard_interrupt_to_checkpoints, *args)
   1228                     # is just to get rid of this extra indentation.
-> 1229                     result = run_impl(runner, async_fn, args)
   1230             except TrioInternalError:

C:\Miniconda3\lib\site-packages\trio\_core\_run.py in run_impl(runner, async_fn, args)
   1356                 # other exceptions as __context__ in unwanted ways.
-> 1357                 runner.task_exited(task, final_result)
   1358             else:

C:\Miniconda3\lib\site-packages\trio\_core\_run.py in task_exited(self, task, result)
    854             # the init task should be the last task to exit
--> 855             assert not self.tasks
    856         else:

AssertionError: 

The above exception was the direct cause of the following exception:

TrioInternalError                         Traceback (most recent call last)
<ipython-input-41-03c750b89f65> in <module>()
----> 1 trio.run(f)

C:\Miniconda3\lib\site-packages\trio\_core\_run.py in run(async_fn, clock, instruments, restrict_keyboard_interrupt_to_checkpoints, *args)
   1233                 raise TrioInternalError(
   1234                     "internal error in trio - please file a bug!"
-> 1235                 ) from exc
   1236             finally:
   1237                 GLOBAL_RUN_CONTEXT.__dict__.clear()

TrioInternalError: internal error in trio - please file a bug!
```

Happy to move this to the `trio_asyncio` repo if that's a more appropriate place...
diff --git a/trio/_core/tests/test_run.py b/trio/_core/tests/test_run.py
index 07798be9..f1ca40f4 100644
--- a/trio/_core/tests/test_run.py
+++ b/trio/_core/tests/test_run.py
@@ -1782,14 +1782,31 @@ def test_nice_error_on_bad_calls_to_run_or_spawn():
 
 
 def test_calling_asyncio_function_gives_nice_error():
-    async def misguided():
+    async def child_xyzzy():
         import asyncio
         await asyncio.Future()
 
+    async def misguided():
+        await child_xyzzy()
+
     with pytest.raises(TypeError) as excinfo:
         _core.run(misguided)
 
     assert "asyncio" in str(excinfo.value)
+    # The traceback should point to the location of the foreign await
+    assert any(  # pragma: no branch
+        entry.name == "child_xyzzy" for entry in excinfo.traceback
+    )
+
+
+async def test_asyncio_function_inside_nursery_does_not_explode():
+    # Regression test for https://github.com/python-trio/trio/issues/552
+    with pytest.raises(TypeError) as excinfo:
+        async with _core.open_nursery() as nursery:
+            import asyncio
+            nursery.start_soon(sleep_forever)
+            await asyncio.Future()
+    assert "asyncio" in str(excinfo.value)
 
 
 async def test_trivial_yields():

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
apt-get update apt-get install -y gcc
3.9
docs-requirements.txt test-requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.12
asn1crypto==0.24.0
astor==0.8.0
astroid==2.2.5
async-generator==1.10
atomicwrites==1.3.0
attrs==19.1.0
Babel==2.7.0
backcall==0.1.0
certifi==2019.6.16
cffi==1.12.3
chardet==3.0.4
Click==7.0
coverage==4.5.4
cryptography==2.7
decorator==4.4.0
docutils==0.15.2
entrypoints==0.3
exceptiongroup==1.2.2
execnet==2.1.1
flake8==3.7.8
idna==2.8
imagesize==1.1.0
immutables==0.9
importlib-metadata==0.19
incremental==17.5.0
iniconfig==2.1.0
ipython==7.7.0
ipython-genutils==0.2.0
isort==4.3.21
jedi==0.14.1
Jinja2==2.10.1
lazy-object-proxy==1.4.1
MarkupSafe==1.1.1
mccabe==0.6.1
more-itertools==7.2.0
outcome==1.0.0
packaging==19.1
parso==0.5.1
pexpect==4.7.0
pickleshare==0.7.5
pluggy==1.5.0
prompt-toolkit==2.0.9
ptyprocess==0.6.0
py==1.8.0
pycodestyle==2.5.0
pycparser==2.19
pyflakes==2.1.1
Pygments==2.4.2
pylint==2.3.1
pyOpenSSL==19.0.0
pyparsing==2.4.2
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==2.7.1
pytest-mock==3.14.0
pytest-xdist==3.6.1
pytz==2019.2
requests==2.22.0
six==1.12.0
sniffio==1.1.0
snowballstemmer==1.9.0
sortedcontainers==2.1.0
Sphinx==2.1.2
sphinx-rtd-theme==0.4.3
sphinxcontrib-applehelp==1.0.1
sphinxcontrib-devhelp==1.0.1
sphinxcontrib-htmlhelp==1.0.2
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.2
sphinxcontrib-serializinghtml==1.1.3
sphinxcontrib-trio==1.1.0
toml==0.10.0
tomli==2.2.1
towncrier==19.2.0
traitlets==4.3.2
-e git+https://github.com/python-trio/trio.git@667d287e1a5aa8a6d7702363844ff2bcbf441b14#egg=trio
trustme==0.5.2
typed-ast==1.5.5
typing_extensions==4.13.0
urllib3==1.25.3
wcwidth==0.1.7
wrapt==1.11.2
yapf==0.27.0
zipp==0.5.2

name: trio
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.12
      - asn1crypto==0.24.0
      - astor==0.8.0
      - astroid==2.2.5
      - async-generator==1.10
      - atomicwrites==1.3.0
      - attrs==19.1.0
      - babel==2.7.0
      - backcall==0.1.0
      - certifi==2019.6.16
      - cffi==1.12.3
      - chardet==3.0.4
      - click==7.0
      - coverage==4.5.4
      - cryptography==2.7
      - decorator==4.4.0
      - docutils==0.15.2
      - entrypoints==0.3
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - flake8==3.7.8
      - idna==2.8
      - imagesize==1.1.0
      - immutables==0.9
      - importlib-metadata==0.19
      - incremental==17.5.0
      - iniconfig==2.1.0
      - ipython==7.7.0
      - ipython-genutils==0.2.0
      - isort==4.3.21
      - jedi==0.14.1
      - jinja2==2.10.1
      - lazy-object-proxy==1.4.1
      - markupsafe==1.1.1
      - mccabe==0.6.1
      - more-itertools==7.2.0
      - outcome==1.0.0
      - packaging==19.1
      - parso==0.5.1
      - pexpect==4.7.0
      - pickleshare==0.7.5
      - pluggy==1.5.0
      - prompt-toolkit==2.0.9
      - ptyprocess==0.6.0
      - py==1.8.0
      - pycodestyle==2.5.0
      - pycparser==2.19
      - pyflakes==2.1.1
      - pygments==2.4.2
      - pylint==2.3.1
      - pyopenssl==19.0.0
      - pyparsing==2.4.2
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==2.7.1
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - pytz==2019.2
      - requests==2.22.0
      - six==1.12.0
      - sniffio==1.1.0
      - snowballstemmer==1.9.0
      - sortedcontainers==2.1.0
      - sphinx==2.1.2
      - sphinx-rtd-theme==0.4.3
      - sphinxcontrib-applehelp==1.0.1
      - sphinxcontrib-devhelp==1.0.1
      - sphinxcontrib-htmlhelp==1.0.2
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.2
      - sphinxcontrib-serializinghtml==1.1.3
      - sphinxcontrib-trio==1.1.0
      - toml==0.10.0
      - tomli==2.2.1
      - towncrier==19.2.0
      - traitlets==4.3.2
      - trio==0.12.1+dev
      - trustme==0.5.2
      - typed-ast==1.5.5
      - typing-extensions==4.13.0
      - urllib3==1.25.3
      - wcwidth==0.1.7
      - wrapt==1.11.2
      - yapf==0.27.0
      - zipp==0.5.2
prefix: /opt/conda/envs/trio

trio/_core/tests/test_run.py::test_calling_asyncio_function_gives_nice_error trio/_core/tests/test_run.py::test_asyncio_function_inside_nursery_does_not_explode
trio/_core/tests/test_run.py::test_instruments_crash trio/_core/tests/test_run.py::test_broken_abort trio/_core/tests/test_run.py::test_error_in_run_loop
trio/_core/tests/test_run.py::test_basic trio/_core/tests/test_run.py::test_initial_task_error trio/_core/tests/test_run.py::test_run_nesting trio/_core/tests/test_run.py::test_nursery_warn_use_async_with trio/_core/tests/test_run.py::test_nursery_main_block_error_basic trio/_core/tests/test_run.py::test_child_crash_basic trio/_core/tests/test_run.py::test_basic_interleave trio/_core/tests/test_run.py::test_task_crash_propagation trio/_core/tests/test_run.py::test_main_and_task_both_crash trio/_core/tests/test_run.py::test_two_child_crashes trio/_core/tests/test_run.py::test_child_crash_wakes_parent trio/_core/tests/test_run.py::test_reschedule trio/_core/tests/test_run.py::test_current_time trio/_core/tests/test_run.py::test_current_time_with_mock_clock trio/_core/tests/test_run.py::test_current_clock trio/_core/tests/test_run.py::test_current_task trio/_core/tests/test_run.py::test_root_task trio/_core/tests/test_run.py::test_out_of_context trio/_core/tests/test_run.py::test_current_statistics trio/_core/tests/test_run.py::test_instruments trio/_core/tests/test_run.py::test_instruments_interleave trio/_core/tests/test_run.py::test_null_instrument trio/_core/tests/test_run.py::test_instrument_before_after_run trio/_core/tests/test_run.py::test_instrument_task_spawn_exit trio/_core/tests/test_run.py::test_cancel_scope_repr trio/_core/tests/test_run.py::test_cancel_points trio/_core/tests/test_run.py::test_cancel_edge_cases trio/_core/tests/test_run.py::test_cancel_scope_multierror_filtering trio/_core/tests/test_run.py::test_precancelled_task trio/_core/tests/test_run.py::test_cancel_shielding trio/_core/tests/test_run.py::test_cancel_inheritance trio/_core/tests/test_run.py::test_cancel_shield_abort trio/_core/tests/test_run.py::test_basic_timeout trio/_core/tests/test_run.py::test_cancel_scope_deprecated trio/_core/tests/test_run.py::test_cancel_scope_nesting trio/_core/tests/test_run.py::test_unshield_while_cancel_propagating trio/_core/tests/test_run.py::test_cancel_unbound trio/_core/tests/test_run.py::test_cancel_scope_misnesting trio/_core/tests/test_run.py::test_timekeeping trio/_core/tests/test_run.py::test_failed_abort trio/_core/tests/test_run.py::test_spawn_system_task trio/_core/tests/test_run.py::test_system_task_crash trio/_core/tests/test_run.py::test_system_task_crash_MultiError trio/_core/tests/test_run.py::test_system_task_crash_plus_Cancelled trio/_core/tests/test_run.py::test_system_task_crash_KeyboardInterrupt trio/_core/tests/test_run.py::test_yield_briefly_checks_for_timeout trio/_core/tests/test_run.py::test_exc_info trio/_core/tests/test_run.py::test_exc_info_after_yield_error trio/_core/tests/test_run.py::test_exception_chaining_after_yield_error trio/_core/tests/test_run.py::test_nursery_exception_chaining_doesnt_make_context_loops trio/_core/tests/test_run.py::test_TrioToken_identity trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_basic trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_too_late trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_idempotent trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_idempotent_requeue trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_after_main_crash trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_crashes trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_FIFO trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_starvation_resistance trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_threaded_stress_test trio/_core/tests/test_run.py::test_TrioToken_run_sync_soon_massive_queue trio/_core/tests/test_run.py::test_slow_abort_basic trio/_core/tests/test_run.py::test_slow_abort_edge_cases trio/_core/tests/test_run.py::test_task_tree_introspection trio/_core/tests/test_run.py::test_nursery_closure trio/_core/tests/test_run.py::test_spawn_name trio/_core/tests/test_run.py::test_current_effective_deadline trio/_core/tests/test_run.py::test_nice_error_on_bad_calls_to_run_or_spawn trio/_core/tests/test_run.py::test_trivial_yields trio/_core/tests/test_run.py::test_nursery_start trio/_core/tests/test_run.py::test_task_nursery_stack trio/_core/tests/test_run.py::test_nursery_start_with_cancelled_nursery trio/_core/tests/test_run.py::test_nursery_start_keeps_nursery_open trio/_core/tests/test_run.py::test_nursery_explicit_exception trio/_core/tests/test_run.py::test_nursery_stop_iteration trio/_core/tests/test_run.py::test_nursery_stop_async_iteration trio/_core/tests/test_run.py::test_traceback_frame_removal trio/_core/tests/test_run.py::test_contextvar_support trio/_core/tests/test_run.py::test_contextvar_multitask trio/_core/tests/test_run.py::test_system_task_contexts trio/_core/tests/test_run.py::test_Nursery_init trio/_core/tests/test_run.py::test_Nursery_private_init trio/_core/tests/test_run.py::test_Nursery_subclass trio/_core/tests/test_run.py::test_Cancelled_init trio/_core/tests/test_run.py::test_Cancelled_str trio/_core/tests/test_run.py::test_Cancelled_subclass trio/_core/tests/test_run.py::test_CancelScope_subclass trio/_core/tests/test_run.py::test_sniffio_integration trio/_core/tests/test_run.py::test_Task_custom_sleep_data trio/_core/tests/test_run.py::test_permanently_detach_coroutine_object trio/_core/tests/test_run.py::test_detach_and_reattach_coroutine_object trio/_core/tests/test_run.py::test_detached_coroutine_cancellation
newsfragments/552.bugfix.rst trio/_core/_run.py
newsfragments/552.bugfix.rst trio/_core/_run.py