{"record":{"id":"2cb4d878d1d35fe6","repo":"xai-org/x-algorithm","slug":"not-an-action-delay-column-column","errorCode":null,"errorMessage":"not an action delay column: {column}","messagePattern":"not an action delay column: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"phoenix/xrex/data/conversion_labels.py","lineNumber":37,"sourceCode":"_PARTITION_SEG_RE = re.compile(r\"(partition=\\d+/)\")\n\n\ndef type_delay_column(conversion_type: str) -> str:\n    sanitized = \"\".join(c if c.isalnum() else \"_\" for c in conversion_type)\n    return f\"{DELAY_COLUMN}_{sanitized}\"\n\n\ndef action_delay_columns(sidecar_path: str) -> list[str]:\n    names = pq.ParquetFile(sidecar_path).schema_arrow.names\n    return sorted(\n        (n for n in names if n.startswith(ACTION_DELAY_PREFIX)),\n        key=lambda n: int(n[len(ACTION_DELAY_PREFIX) :]),\n    )\n\n\ndef action_index_of(column: str) -> int:\n    if not column.startswith(ACTION_DELAY_PREFIX):\n        raise ValueError(f\"not an action delay column: {column}\")\n    return int(column[len(ACTION_DELAY_PREFIX) :])\n\n\ndef sidecar_path_for(batch_file_path: str) -> str:\n    m = _PARTITION_SEG_RE.search(batch_file_path)\n    if m is None:\n        raise ValueError(f\"not a partition batch file path: {batch_file_path}\")\n    root = batch_file_path[: m.start()]\n    rel = batch_file_path[m.start() :]\n    if not rel.endswith(\".parquet\"):\n        raise ValueError(f\"not a parquet path: {batch_file_path}\")\n    return os.path.join(root, \"labels\", rel[: -len(\".parquet\")] + \".labels.parquet\")\n\n\ndef load_sidecar_delays(\n    sidecar_path: str, columns: list[str] | None = None\n) -> dict[str, np.ndarray]:\n    columns = columns or [DELAY_COLUMN]","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/phoenix/xrex/data/conversion_labels.py#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Filter the column list with the same prefix check before calling: cols = [c for c in df.columns if c.startswith(ACTION_DELAY_PREFIX)]","Verify the exact prefix spelling (import ACTION_DELAY_PREFIX and use it, do not hard-code)","Strip/normalize column names (whitespace, case) before matching","If a non-delay column must be handled, branch on the prefix instead of calling action_index_of unconditionally"],"exampleFix":"# before\nidx = action_index_of(col)  # col may be 'score'\n# after\nif col.startswith(ACTION_DELAY_PREFIX):\n    idx = action_index_of(col)\nelse:\n    continue","handlingStrategy":"type-guard","validationCode":"delay_cols = [c for c in df.columns if c.startswith(ACTION_DELAY_PREFIX)]\nindices = [action_index_of(c) for c in delay_cols]","typeGuard":"def is_action_delay_column(col: str) -> bool:\n    return isinstance(col, str) and col.startswith(ACTION_DELAY_PREFIX)","tryCatchPattern":"try:\n    idx = action_index_of(col)\nexcept ValueError:\n    logger.debug('skipping non-delay column %s', col)\n    idx = None","preventionTips":["Always filter columns by ACTION_DELAY_PREFIX before indexing","Import the prefix constant instead of hard-coding the string","Add schema checks on batch files before feature folding"],"tags":["python","data-pipeline","column-naming","validation","feature-engineering"],"backgroundTag":"column-prefix-validation-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}