alibaba/DataX · error · RuntimeException

TRANSFORMER_RUN_EXCEPTION

TRANSFORMER_RUN_EXCEPTION

Error message

dx_replace startIndex(%s) out of range(%s)

What it means

Thrown by dx_replace when startIndex exceeds the length of the column's string value, because String.substring cannot begin past the end of the string. The value is read per record via column.asString() (null values are skipped), so this is a data-dependent runtime error wrapped as TRANSFORMER_RUN_EXCEPTION, not a configuration error.

Source

Thrown at core/src/main/java/com/alibaba/datax/core/transport/transformer/ReplaceTransformer.java:51

            startIndex = Integer.valueOf((String) paras[1]);
            length = Integer.valueOf((String) paras[2]);
            replaceString = (String) paras[3];
        } catch (Exception e) {
            throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER, "paras:" + Arrays.asList(paras).toString() + " => " + e.getMessage());
        }

        Column column = record.getColumn(columnIndex);

        try {
            String oriValue = column.asString();

            //如果字段为空,跳过replace处理
            if(oriValue == null){
                return  record;
            }
            String newValue;
            if (startIndex > oriValue.length()) {
                throw new RuntimeException(String.format("dx_replace startIndex(%s) out of range(%s)", startIndex, oriValue.length()));
            }
            if (startIndex + length >= oriValue.length()) {
                newValue = oriValue.substring(0, startIndex) + replaceString;
            } else {
                newValue = oriValue.substring(0, startIndex) + replaceString + oriValue.substring(startIndex + length, oriValue.length());
            }

            record.setColumn(columnIndex, new StringColumn(newValue));

        } catch (Exception e) {
            throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_RUN_EXCEPTION, e.getMessage(),e);
        }
        return record;
    }
}

View on GitHub (pinned to 80ec23d5c5)

Solutions

  1. Lower startIndex so it is <= the length of the shortest non-null value in the column.
  2. Pre-filter or pad short values with dx_pad before dx_replace in the transformer chain.
  3. Inspect the failing record (the DataX log shows the record and column index) to see the actual short value and adjust the parameters accordingly.

Example fix

// before: value "abc", startIndex 5
"paras": [2, "5", "3", "X"]
// after: start within shortest value
"paras": [2, "2", "3", "X"]
Defensive patterns

Strategy: validation

Validate before calling

// before applying dx_replace, ensure every non-null value is long enough
String v = record.getColumn(idx).asString();
if (v != null && v.length() < startIndex) {
    v = String.format("%-" + startIndex + "s", v); // pad right to safe length
    record.setColumn(idx, new StringColumn(v));
}

Try / catch

catch (DataXException e) when TRANSFORMER_RUN_EXCEPTION: log record + column value, route record to a dirty channel instead of aborting the task.

Prevention

When it happens

Trigger: A record whose target column contains a string shorter than startIndex, e.g. startIndex=5 applied to the value "abc". The comparison is strict (startIndex > length), so startIndex == length is allowed and produces a pure append; anything greater throws.

Common situations: Fixed startIndex chosen against the longest expected value, but the source table later contains shorter rows; null-vs-empty-string confusion (empty strings are processed, nulls are skipped); multi-byte characters where Java length counts UTF-16 chars.

Related errors


AI-assisted analysis of alibaba/DataX@80ec23d5c5 (2026-08-14). Data as JSON: /api/errors/88fae18cf489d83c. Report an issue: GitHub.