> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oasm.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Adapter

> The Validate and Execute methods every connector implements, plus the error convention the worker uses to decide retries

The adapter is the only code every connector must write. It implements two methods and does nothing else — no lifecycle, no connection, no stream management.

```go theme={null}
package connector

import "context"

// Adapter is the tool-specific implementation that each connector provides.
type Adapter interface {
    Validate(ctx context.Context, inputs map[string]any) error
    Execute(ctx context.Context, inputs map[string]any, out chan<- Finding) error
}
```

## `Validate`

Rejects inputs the tool cannot possibly run, **before** any container or network resource is spent.

```go theme={null}
func (a *MyAdapter) Validate(ctx context.Context, inputs map[string]any) error
```

* Runs before execution. Keep it cheap — no network calls, no process spawns.
* Return an error to block the run; return `nil` to allow it.
* Upstream validation against the connector's `inputsSchema` already runs in the worker, so this is a second line of defense for anything the schema cannot express.

```go theme={null}
func (a *MyAdapter) Validate(_ context.Context, inputs map[string]any) error {
    target, _ := inputs["target"].(string)
    if strings.TrimSpace(target) == "" {
        return fmt.Errorf("fatal: target is required")
    }
    return nil
}
```

## `Execute`

Runs the tool and streams findings to `out`.

```go theme={null}
func (a *MyAdapter) Execute(ctx context.Context, inputs map[string]any, out chan<- connector.Finding) error
```

Rules:

* **Stream, do not buffer.** Send each finding to `out` as it is produced. A long scan should return results before it finishes.
* **Honor cancellation.** Stop when `ctx.Done()` is closed — the runtime may cancel a run mid-flight. `select` on `ctx.Done()` when sending.
* **Never close `out`.** The runtime owns the channel.
* Keep tool-specific code in this package and nowhere else.

```go theme={null}
func (a *MyAdapter) Execute(ctx context.Context, inputs map[string]any, out chan<- connector.Finding) error {
    target, _ := inputs["target"].(string)

    findings, err := a.runTool(ctx, target) // your tool
    if err != nil {
        return fmt.Errorf("retryable: run tool: %w", err)
    }
    for _, raw := range findings {
        f, mapErr := toFinding(raw) // map scanner output -> connector.Finding
        if mapErr != nil {
            continue // skip unparseable items rather than failing the run
        }
        select {
        case out <- f:
        case <-ctx.Done():
            return ctx.Err()
        }
    }
    return nil
}
```

## Error convention

The worker uses an error's prefix to decide whether to retry. Apply the prefix to every error you return.

| Prefix | Meaning | Examples |
| - | - | - |
| `fatal: ` | Configuration, credentials, or target problems. Retrying will not help. | Missing target, invalid API token, malformed input. |
| `retryable: ` | Transient failures. The worker may retry. | Dial timeout, tool crash, network error, cancellation. |

The SDK applies the prefix to errors it raises itself. An error with no prefix is treated as retryable.

```go theme={null}
return fmt.Errorf("fatal: invalid credentials: %w", err)
return fmt.Errorf("retryable: scanner exited: %w", err)
```

## Wrapping the adapter

`connector.New` wraps your adapter so the runtime can drive it. You do not call `Validate` or `Execute` yourself.

```go theme={null}
import sdkconn "github.com/oasm-platform/oasm-connectors/sdk/connector"

conn := sdkconn.New(&MyAdapter{})
```

## Design notes

* **Prefer in-process embedding over a CLI wrapper** where the tool offers a library — no subprocess lifecycle, no output-format drift, cancellation propagates naturally.
* **Remote-API tools ship no bundled binary.** The adapter is the client; credentials belong in `configSchema`, never in code or the image.
* **Map severities explicitly** with a lookup table, not string guessing. See [Finding](/connectors/finding).
* **Never leak secrets into findings or logs.** Findings are persisted and displayed; config values are not.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.