zed-industries/zed · error · RuntimeError

Option '{option_name}' not found in field '{field_name}'

Error message

Option '{option_name}' not found in field '{field_name}'

What it means

After the field is found, set_project_field needs the id of the single-select option whose name equals option_name; when no option matches it raises before sending updateProjectV2ItemFieldValue. The mutation only accepts option ids, so a name the field does not define cannot be written.

Source

Thrown at script/github-guild-board.py:304

    )
    node = data.get("node") or {}
    for item in (node.get("projectItems") or {}).get("nodes", []):
        if item["project"]["id"] == project_id:
            return item
    return None


def set_project_field(project, item_id, field_name, option_name):
    field = next(
        (f for f in project["fields"]["nodes"] if f.get("name") == field_name), None
    )
    if not field:
        raise RuntimeError(f"Field '{field_name}' not found on board")
    option_id = next(
        (o["id"] for o in field.get("options", []) if o["name"] == option_name), None
    )
    if not option_id:
        raise RuntimeError(f"Option '{option_name}' not found in field '{field_name}'")
    github_graphql(
        """
        mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
          updateProjectV2ItemFieldValue(input: {
            projectId: $projectId, itemId: $itemId, fieldId: $fieldId,
            value: { singleSelectOptionId: $optionId }
          }) { projectV2Item { id } }
        }
        """,
        {
            "projectId": project["id"],
            "itemId": item_id,
            "fieldId": field["id"],
            "optionId": option_id,
        },
    )

View on GitHub (pinned to bc538def45)

Solutions

  1. Read field['options'] (already fetched) and update the script to pass an option that exists
  2. Add the missing option to the single-select field on the project if the state is legitimate
  3. Normalize case/whitespace when comparing option names
  4. Validate the full expected option set at startup

Example fix

// before
option_id = next((o["id"] for o in field.get("options", []) if o["name"] == option_name), None)
if not option_id:
    raise RuntimeError(f"Option '{option_name}' not found in field '{field_name}'")

// after
option_id = next(
    (o["id"] for o in field.get("options", []) if o["name"].strip().lower() == option_name.strip().lower()),
    None,
)
if not option_id:
    available = [o["name"] for o in field.get("options", [])]
    raise RuntimeError(f"Option '{option_name}' not found in field '{field_name}'; available: {available}")
Defensive patterns

Strategy: validation

Validate before calling

def field_has_option(field: dict, option_name: str) -> bool:
    return any(o.get("name") == option_name for o in field.get("options", []))

Type guard

def option_id_if_present(field: dict, option_name: str) -> str | None:
    return next((o["id"] for o in field.get("options", []) if o.get("name") == option_name), None)

Try / catch

try:
    set_project_field(project, item_id, STATUS_FIELD, option)
except RuntimeError as exc:
    if "not found in field" in str(exc):
        log(f"Option drift: {exc}")
    else:
        raise

Prevention

When it happens

Trigger: The guild board's Status option vocabulary differs from what the script passes: an option like "In Progress" was renamed or never existed on this board, or the script maps a state to an option added only on another project.

Common situations: Workflow status renames on the board; new states added to the script but not to the field's option list; whitespace or case drift between script strings and board options.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/1bb05bd314647591. Report an issue: GitHub.