xai-org/x-algorithm · error · ValueError

not an action delay column: {column}

Error message

not an action delay column: {column}

What it means

action_index_of extracts the numeric suffix of feature columns named with the ACTION_DELAY prefix (e.g. 'action_delay_0', 'action_delay_1', ...). It raises when given a string that does not start with that prefix, guarding fold_action_delays_into_multihot from silently mis-mapping columns to wrong multihot slots.

Source

Thrown at phoenix/xrex/data/conversion_labels.py:37

_PARTITION_SEG_RE = re.compile(r"(partition=\d+/)")


def type_delay_column(conversion_type: str) -> str:
    sanitized = "".join(c if c.isalnum() else "_" for c in conversion_type)
    return f"{DELAY_COLUMN}_{sanitized}"


def action_delay_columns(sidecar_path: str) -> list[str]:
    names = pq.ParquetFile(sidecar_path).schema_arrow.names
    return sorted(
        (n for n in names if n.startswith(ACTION_DELAY_PREFIX)),
        key=lambda n: int(n[len(ACTION_DELAY_PREFIX) :]),
    )


def action_index_of(column: str) -> int:
    if not column.startswith(ACTION_DELAY_PREFIX):
        raise ValueError(f"not an action delay column: {column}")
    return int(column[len(ACTION_DELAY_PREFIX) :])


def sidecar_path_for(batch_file_path: str) -> str:
    m = _PARTITION_SEG_RE.search(batch_file_path)
    if m is None:
        raise ValueError(f"not a partition batch file path: {batch_file_path}")
    root = batch_file_path[: m.start()]
    rel = batch_file_path[m.start() :]
    if not rel.endswith(".parquet"):
        raise ValueError(f"not a parquet path: {batch_file_path}")
    return os.path.join(root, "labels", rel[: -len(".parquet")] + ".labels.parquet")


def load_sidecar_delays(
    sidecar_path: str, columns: list[str] | None = None
) -> dict[str, np.ndarray]:
    columns = columns or [DELAY_COLUMN]

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Filter the column list with the same prefix check before calling: cols = [c for c in df.columns if c.startswith(ACTION_DELAY_PREFIX)]
  2. Verify the exact prefix spelling (import ACTION_DELAY_PREFIX and use it, do not hard-code)
  3. Strip/normalize column names (whitespace, case) before matching
  4. If a non-delay column must be handled, branch on the prefix instead of calling action_index_of unconditionally

Example fix

# before
idx = action_index_of(col)  # col may be 'score'
# after
if col.startswith(ACTION_DELAY_PREFIX):
    idx = action_index_of(col)
else:
    continue
Defensive patterns

Strategy: type-guard

Validate before calling

delay_cols = [c for c in df.columns if c.startswith(ACTION_DELAY_PREFIX)]
indices = [action_index_of(c) for c in delay_cols]

Type guard

def is_action_delay_column(col: str) -> bool:
    return isinstance(col, str) and col.startswith(ACTION_DELAY_PREFIX)

Try / catch

try:
    idx = action_index_of(col)
except ValueError:
    logger.debug('skipping non-delay column %s', col)
    idx = None

Prevention

When it happens

Trigger: Calling action_index_of (directly or via fold_action_delays_into_multihot) with a column name lacking the ACTION_DELAY prefix — e.g. 'delay_3', 'action_delays_4', a plain feature name, or an empty string.

Common situations: Renaming schema columns in the parquet/batch files without updating the prefix constant; passing an index or integer instead of the column string; downstream code iterating over all dataframe columns and forgetting to filter to delay columns first.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/2cb4d878d1d35fe6. Report an issue: GitHub.