{"record":{"id":"b6686d8b42ac6aab","repo":"openzipkin/zipkin","slug":"parentid-is-empty","errorCode":null,"errorMessage":"parentId is empty","messagePattern":"parentId is empty","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/Span.java","lineNumber":433,"sourceCode":"    }\n\n    /** Hex encodes the input as the {@link Span#parentId()} or unsets if the input is zero. */\n    public Builder parentId(long parentId) {\n      this.parentId = parentId != 0L ? toLowerHex(parentId) : null;\n      return this;\n    }\n\n    /**\n     * Sets {@link Span#parentId()} or throws {@link IllegalArgumentException} if not lower-hex\n     * format.\n     */\n    public Builder parentId(@Nullable String parentId) {\n      if (parentId == null) {\n        this.parentId = null;\n        return this;\n      }\n      int length = parentId.length();\n      if (length == 0) throw new IllegalArgumentException(\"parentId is empty\");\n      if (length > 16) throw new IllegalArgumentException(\"parentId.length > 16\");\n      if (validateHexAndReturnZeroPrefix(parentId) == length) {\n        this.parentId = null;\n      } else {\n        this.parentId = length < 16 ? padLeft(parentId, 16) : parentId;\n      }\n      return this;\n    }\n\n    /**\n     * Hex encodes the input as the {@link Span#id()} or throws IllegalArgumentException if the\n     * input is zero.\n     */\n    public Builder id(long id) {\n      if (id == 0L) throw new IllegalArgumentException(\"empty id\");\n      this.id = toLowerHex(id);\n      return this;\n    }","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/Span.java#L415-L451","documentation":"Span.Builder.parentId(String) throws IllegalArgumentException('parentId is empty') when the argument is a non-null, zero-length string. An empty string is neither a valid ID nor the canonical way to say 'no parent' — that is null (or a zero-valued ID, which this method converts to null). The check happens before length/hex validation.","triggerScenarios":"Calling .parentId(\"\") or parentId(someHeader) where the header was present but blank; passing a substring or trimmed value that ended up empty.","commonSituations":"Forwarding parent-span headers (x-b3-parentspanid, traceparent's parent-id part) into the builder without checking for blank values — common in proxies, filters, and Spring HandlerInterceptors that map headers 1:1 to builder calls.","solutions":["Convert empty to null before calling: .parentId(isEmpty(parentId) ? null : parentId).","Guard at the extraction boundary: treat a blank header as 'no parent span' when reading B3/traceparent headers.","Log which header produced the blank value so misconfigured upstream services can be identified."],"exampleFix":"// before\nb.parentId(request.getHeader(\"x-b3-parentspanid\"));\n\n// after\nString p = request.getHeader(\"x-b3-parentspanid\");\nb.parentId(p == null || p.isEmpty() ? null : p);","handlingStrategy":"validation","validationCode":"String normalizeParentId(String p) {\n  return (p == null || p.isEmpty()) ? null : p;\n}\n// b.parentId(normalizeParentId(header));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize header extraction so blank parent IDs become null in exactly one place.","Unit-test header mapping with blank ('') and missing header cases."],"tags":["zipkin","span","parent-id","validation","builder"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}