---
url: >-
  https://adk.nht.io/api/@nhtio/adk/batteries/sandbox/tools/functions/narratingPath.md
---

# Function: narratingPath()

```ts
function narratingPath<T>(
  operation: () => T | Promise<T>,
  input: string,
): Promise<T>;
```

Defined in: [src/batteries/sandbox/tools/index.ts:132](https://github.com/NHTIO/ADK/blob/master/src/src/batteries/sandbox/tools/index.ts#L132)

Run a `PathTranslator` operation and narrate any refusal it raises.

## Type Parameters

| Type Parameter |
| -------------- |
| `T`            |

## Parameters

| Parameter   | Type                          | Description                                          |
| ----------- | ----------------------------- | ---------------------------------------------------- |
| `operation` | () => `T` | `Promise`<`T`> | The translator call.                                 |
| `input`     | `string`                      | The model-supplied path, echoed back in the outcome. |

## Returns

`Promise`<`T`>

The operation's result.

## Remarks

EVERY translator call must go through here, not just the obvious `toRelative`. `toBackendPath` and
`assertNoSymlinkComponents` both reject — the latter is the symlinked-component refusal, which is a
security control — and a bare call lets that escape as the translator's native error, bypassing the
narrator seam the whole battery depends on. The model then receives an unactionable message for the
one class of failure it could actually correct.

An already-narrated exception passes through untouched, so wrapping a call that itself narrates is
safe and the outcome is never rendered twice.
