t8y2/dbx · error · IllegalArgumentException

timestampMs is required when position is timestamp

Error message

timestampMs is required when position is timestamp

What it means

offsetSpecForPosition maps a "position" string to a Kafka OffsetSpec. When position is "timestamp", a companion timestampMs value is mandatory; if it is null the agent throws IllegalArgumentException (KafkaAgent.java:1569).

Source

Thrown at agents/drivers/kafka/src/main/java/com/dbx/agent/kafka/KafkaAgent.java:1569

        try {
            java.math.BigDecimal decimal = element.getAsBigDecimal();
            if (decimal.signum() < 0 || decimal.stripTrailingZeros().scale() > 0) {
                throw new IllegalArgumentException(name + " must be a non-negative integer");
            }
            return decimal.longValueExact();
        } catch (ArithmeticException error) {
            throw new IllegalArgumentException(name + " is outside the supported integer range", error);
        }
    }

    static OffsetSpec offsetSpecForPosition(String position, Long timestampMs) {
        String normalized = position == null ? "latest" : position.trim().toLowerCase(Locale.ROOT);
        return switch (normalized) {
            case "earliest" -> OffsetSpec.earliest();
            case "latest", "" -> OffsetSpec.latest();
            case "timestamp" -> {
                if (timestampMs == null) {
                    throw new IllegalArgumentException("timestampMs is required when position is timestamp");
                }
                yield OffsetSpec.forTimestamp(timestampMs);
            }
            default -> throw new IllegalArgumentException("Unsupported reset position: " + position);
        };
    }

    // -----------------------------------------------------------------------
    // Messages
    // -----------------------------------------------------------------------

    private static Object peekMessages(JsonObject params) throws Exception {
        String topic = stringOrEmpty(params, "topic");
        Integer partition = integerOrNull(params, "partition");
        Long offset = longOrNull(params, "offset");
        int count = validatedPeekCount(intOrDefault(params, "count", 10));
        PeekStartPosition startPosition = peekStartPosition(params);
        boolean explicitStartPosition = stringOrNull(params, "startPosition") != null;

View on GitHub (pinned to c0390bff16)

Solutions

  1. Provide timestampMs (epoch milliseconds as a number) whenever position is "timestamp"
  2. Use position "earliest" or "latest" if a point-in-time lookup is not actually needed
  3. Verify the params object still contains timestampMs after serialization

Example fix

// before
params.put("position", "timestamp");
// after
params.put("position", "timestamp");
params.put("timestampMs", 1712000000000L);
Defensive patterns

Strategy: validation

Validate before calling

if (position === 'timestamp' && (timestampMs == null || typeof timestampMs !== 'number')) throw new Error('timestampMs required');

Type guard

function timestampReady(p){ return p.position !== 'timestamp' || (typeof p.timestampMs === 'number' && p.timestampMs >= 0); }

Try / catch

try { agent.execute(req); } catch (e) { if (String(e.message).includes('timestampMs is required')) { /* add timestampMs or change position */ } else throw e; }

Prevention

When it happens

Trigger: Calling the offset-listing/reset operation with position="timestamp" (any casing/whitespace) but omitting timestampMs, or passing it as null.

Common situations: Config templates that set position but forget the timestamp parameter; timestamps stripped by an intermediate serializer that drops nulls.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/605bd954f1a90de8. Report an issue: GitHub.