Offering match options in a review step
Write a script that tells a review step which values a reviewer may choose from for a cell, so they pick from real candidates instead of typing a value by hand.
A review step exists because a value could not be resolved automatically. Filtering on every key you have still leaves more than one possibility, so a person has to decide which one is right.
The Match options script is how you tell the review step what those possibilities are. It runs once when a run pauses for review, and every cell it narrows becomes a dropdown of exactly those values. Cells the script says nothing about stay ordinary text fields.
Writing the script
Open the review step's settings and find the Match options section. Your script receives the rows of the data under review and calls setOptions for each cell it can narrow:
import { Row } from "oneschema/reviewoptions"
const TAX_CODES = [
{ code: "340602", name: "Pocono Twp", county: "Monroe", locality: "POCONO T" },
{ code: "340603", name: "Pocono Twp SD", county: "Monroe", locality: "POCONO T" },
{
code: "340810",
name: "Shillington Boro",
county: "Berks",
locality: "SHILLINGTON B",
},
]
export default function (rows: Row[]) {
rows.forEach((row) => {
// Already resolved upstream — leave it alone.
if (row.values["Tax Code"]) return
const candidates = TAX_CODES.filter((c) => c.locality === row.values["Locality"])
row.setOptions(
"Tax Code",
candidates.map((c) => ({
value: c.code,
label: c.name,
description: c.county,
})),
)
})
}A reviewer working the Tax Code column now sees the two Pocono codes on the POCONO T row, and nothing at all on the row that was already resolved.
The Row object
Row object| Property | Description |
|---|---|
row.id | Identifier for the row. Stable while the run is paused. |
row.values | The row's cells, keyed by column name. |
row.setOptions(column, opts) | Offer opts to the reviewer for this row's column. |
Say nothing about a cell and it stays a text field, so a script only has to speak up where it can genuinely narrow things down. Calling setOptions twice for the same cell replaces the earlier list.
The Option object
Option object| Field | Required | Description |
|---|---|---|
value | Yes | Written into the cell when the reviewer picks it, so it must be the value your later steps expect. A number is accepted and stored as its string form. |
label | No | Shown beside the value. When omitted, the value is shown on its own. |
description | No | Secondary text, for telling near-identical candidates apart. |
label and description exist for the situation this feature is for: when two candidates differ by something a bare code does not show. A reviewer recognizes "Pocono Twp SD" long before they recognize 340603.
Reading your own reference data
The script has no special access to the reference file configured on the step. Either include the lookup table in the script, as above, or fetch it:
import { fetch } from "oneschema"
export default async function (rows: Row[]) {
const response = await fetch("https://example.com/tax-codes")
const codes = await response.json()
// …
}Network access is off unless outbound requests are enabled for your organization — the same setting that enables validation webhooks. Contact support if your script needs it.
Working with the columns
findColumn and getColumns describe the data under review, which is useful when column names vary between files:
import { Row, getColumns } from "oneschema/reviewoptions"
export default function (rows: Row[]) {
const codeColumns = getColumns().filter((c) => c.key.endsWith(" Code"))
// …
}| Function | Returns |
|---|---|
getColumns() | Every column, in the order the reviewer sees them. |
findColumn(key) | One column by key, or undefined when the data has no such column. |
A column's key here is its name in the data under review — the same string you use to read a cell from row.values and to name a column in setOptions. That differs from a validation code hook, where the key is the template's target attribute: a review step need not have a template at all, so it works from the column names the data actually carries.
What a reviewer sees
- Cells you narrowed open a dropdown of your candidates, searchable by value or label.
- Cells you said nothing about stay ordinary text fields.
- A reviewer can always type a value you did not offer. The review step exists because the decision needed a person, so when your narrowing is wrong they are never boxed in by it.
When options do not appear
The script is a convenience, so a failure never blocks a review — the run still pauses and the affected cells stay text fields. Options are missing when:
- No script is configured on the step.
- The script ran without narrowing any cell.
- The script raised an error. The failure is recorded on the step for support to look into; there is no self-serve view of it yet.
- The script offered options for an implausible number of cells. A review is human-scale; a script narrowing thousands of cells is usually doing something other than helping a person decide.
Limits
| Limit | Value |
|---|---|
| Options per cell | 1,000 |
| Cells with options per file | 5,000 |
| Script run time | Shares the code-hook timeout for your organization |
Exceeding either count is reported as an error rather than silently truncated.
Updated about 3 hours ago