{"record":{"id":"d70835f69b9892b7","repo":"openzipkin/zipkin","slug":"endts-0-d70835","errorCode":null,"errorMessage":"endTs <= 0","messagePattern":"endTs <= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/storage/InMemoryStorage.java","lineNumber":419,"sourceCode":"    return Call.create(new ArrayList<>(serviceToTraceIds.keySet()));\n  }\n\n  @Override public synchronized Call<List<String>> getRemoteServiceNames(String service) {\n    if (service.isEmpty() || !searchEnabled) return Call.emptyList();\n    service = service.toLowerCase(Locale.ROOT); // service names are always lowercase!\n    return Call.create(\n        new ArrayList<>(serviceToRemoteServiceNames.get(service)));\n  }\n\n  @Override public synchronized Call<List<String>> getSpanNames(String service) {\n    if (service.isEmpty() || !searchEnabled) return Call.emptyList();\n    service = service.toLowerCase(Locale.ROOT); // service names are always lowercase!\n    return Call.create(new ArrayList<>(serviceToSpanNames.get(service)));\n  }\n\n  @Override\n  public synchronized Call<List<DependencyLink>> getDependencies(long endTs, long lookback) {\n    if (endTs <= 0) throw new IllegalArgumentException(\"endTs <= 0\");\n    if (lookback <= 0) throw new IllegalArgumentException(\"lookback <= 0\");\n\n    Set<String> lowTraceIdsInRange =\n      lowTraceIdsInRange(spansByTraceIdTimestamp.keySet(), endTs, lookback);\n    List<DependencyLink> links = getDependencyLinks(lowTraceIdsInRange);\n    return Call.create(links);\n  }\n\n  // We don't have a query parameter for strictTraceId when fetching dependency links, so we\n  // ignore traceIdHigh. Otherwise, a single trace can appear as two, doubling callCount.\n  List<DependencyLink> getDependencyLinks(Set<String> lowTraceIdsInRange) {\n    if (lowTraceIdsInRange.isEmpty()) return Collections.emptyList();\n    DependencyLinker linksBuilder = new DependencyLinker();\n    for (String lowTraceId : lowTraceIdsInRange) {\n      linksBuilder.putTrace(spansByTraceId(lowTraceId));\n    }\n    return linksBuilder.link();\n  }","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/storage/InMemoryStorage.java#L401-L437","documentation":"InMemoryStorage.getDependencies(endTs, lookback) computes dependency links for a time window ending at endTs; endTs is epoch milliseconds and must be positive. Zero or negative throws IllegalArgumentException('endTs <= 0') (lookback gets an equivalent check). It is a fail-fast guard against nonsensical time windows, often exposing a units bug.","triggerScenarios":"Calling storage.getDependencies(0, lookback) or with a negative endTs — e.g. passing epoch *seconds* multiplied wrongly, an unset default long (0), or System.currentTimeMillis() mocked to 0 in tests.","commonSituations":"Calling the dependency endpoint /dependencies?endTs=... with a non-numeric/blank value that parses to 0; unit confusion (seconds vs millis); request DTO defaults of 0L forwarded without validation.","solutions":["Pass endTs as epoch milliseconds (e.g. System.currentTimeMillis()); lookback in millis too.","Validate request parameters at the API edge: reject endTs<=0 with 400 before calling storage.","In tests, fix the clock or pass explicit positive timestamps.","Check for request models where endTs is a primitive long defaulting to 0 when the client omits it."],"exampleFix":"// before\nlong endTs = request.getEndTs(); // defaults to 0 when client omits it\nstorage.getDependencies(endTs, lookback);\n\n// after\nlong endTs = request.getEndTs() > 0 ? request.getEndTs() : System.currentTimeMillis();\nstorage.getDependencies(endTs, lookback);","handlingStrategy":"validation","validationCode":"if (endTs <= 0 || lookback <= 0) throw new ResponseStatusException(BAD_REQUEST, \"endTs and lookback must be positive epoch millis\");","typeGuard":"boolean isValidTimeWindow(long endTs, long lookback) { return endTs > 0 && lookback > 0; }","tryCatchPattern":null,"preventionTips":["Standardize on epoch milliseconds end-to-end.","Never forward primitive-long request defaults (0) into storage calls."],"tags":["zipkin","query","dependencies","validation"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}