---
title: paramsOf
description: Read the params of a pick from the event that entered the state.
---

# `paramsOf`

Function, in `@jr2/orchestrator/src/pick.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.

```ts
function paramsOf<
  N extends string,
  I extends z.ZodObject,
>(
  event: EventObject,
  def: EventDef<N, I>,
): z.infer<I>
```

Read the params of a pick from the event that entered the state. Use it in a plain `input`
mapper when the Machine must change a param before the invoked actor gets it. When the params go
to the input as they are, use `fromPick`.

It parses the params with the `input` schema of the pick. It refuses an event that is not this
pick: `state entered by "<event>", but its input reads the params of pick "<pick>"`.

`createMachine` calls each mapper one time to see which params it reads. When the mapper throws
there, `jr2 up` prints a warning before a run starts: `pick "<pick>" enters state "<state>"
(Effect "<slot>"): could not probe the input mapper (<error>); its params are unchecked`.

`createMachine` refuses a param of a pick that enters a state that invokes an Effect, when
nothing reads the param: `machine "<id>": pick "<pick>" enters state "<state>" (Effect
"<slot>"), which never reads "<param>": the Agent supplies it and nothing uses it — map it in an
invoke's input, store it with assign, or drop it from the def`.

**Parameters**

- `event`: The event that entered the state: the `event` that the mapper gets.
- `def` ([`EventDef`](type-eventdef.md)): The pick, as `defineEvent` made it.

**Returns**: The params of the pick, typed by its `input` schema.

**Example**

```ts
import { z } from "zod";
import {
  agent,
  arg,
  command,
  defineEvent,
  fail,
  jr2Setup,
  paramsOf,
  workspace,
  type Workspaced,
} from "@jr2/orchestrator";

const runTest = defineEvent({
  name: "run_test",
  description: "Run the tests of one module.",
  input: z.object({ module: z.string() }),
});

const finished = defineEvent({
  name: "finished",
  description: "Say that all the tests pass.",
  input: z.object({}),
});

type Input = Workspaced<{}, "app">;

const body = jr2Setup({
  types: {} as { context: Input; input: Input },
  events: [runTest, finished],
  actors: {
    coder: agent({
      model: "anthropic/claude-haiku-5-5",
      instructions: "You are a careful engineer.",
    }),
    test: command(["node", "--test", arg("file")]),
    fail: fail(),
  },
}).createMachine({
  id: "fix-tests",
  context: ({ input }) => input,
  on: { "workspace.lost": ".lost", "agent.fault": ".failed" },
  initial: "coding",
  states: {
    coding: {
      invoke: {
        src: "coder",
        input: { prompt: "Make the tests pass. Run the tests of one module at a time." },
      },
      on: { finished: "done" },
      initial: "ready",
      states: {
        ready: { on: { run_test: "testing" } },
        testing: {
          invoke: {
            src: "test",
            // A plain mapper: the Machine makes the file name from the pick's `module`.
            input: ({ event }) => ({ file: `test/${paramsOf(event, runTest).module}.test.js` }),
            onDone: "ready",
          },
        },
      },
    },
    done: { type: "final" },
    failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
    lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
  },
});

export const machine = workspace(body, {
  repos: { app: { url: "https://github.com/you/app.git" } },
  spec: () => ({ branch: "fix-tests" }),
});
```

**See also**

- [Effects](../../concepts/effects.md)
- [Run a command or call a URL with an Effect](../../guides/run-a-command-or-call-a-url.md)
- [ADR-0067: An Effect is an actor slot, and runs at most once unless marked idempotent](../decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md)
