apple/pkl · error · ParserError

danglingDocComment

danglingDocComment

Error message

Dangling documentation comment.

Documentation comments must be attached to modules, classes, typealiases, methods, or properties.

What it means

A `///` documentation comment was found where it cannot attach to any declaration — at top level it must directly precede a module header, class, typealias, method, or property. parseModuleMember throws "Dangling documentation comment" when a DOC_COMMENT token appears where no attachable member follows.

Solutions

  1. Remove the orphaned `///` comment, or convert it to a plain `//` comment.
  2. Re-attach it directly above the class/typealias/method/property it documents (no intervening tokens).
  3. If it documents the module itself, place it above the module `amends`/`extends` header at the top of the file.
  4. Check the code after the comment wasn't accidentally deleted during refactoring.

Example fix

// before
/// This documented something, but the code below is gone.
}
// after — either delete the comment or attach it to a real declaration:
/// Describes the bird's name.
name: String
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every '///' comment is immediately followed by a declaration-looking line
function danglingDocComments(lines) {
  const decl = /^\s*(class\b|typealias\b|function\b|`?[A-Za-z_]\w*`?\s*(:|=|\())|^(amends|extends)\b/;
  return lines
    .map((l, i) => [l.trim(), i])
    .filter(([l, i]) => l.startsWith('///') && (i + 1 >= lines.length || !decl.test(lines[i + 1])))
    .map(([, i]) => i + 1);
}

Prevention

When it happens

Trigger: A `///` comment at the end of the file with no declaration after it; a `///` comment separated from its declaration by a blank line is fine, but one followed by another comment, an import, or a closing brace dangles; doc comment placed inside a block or between imports.

Common situations: Deleting a declaration but leaving its doc comment behind; refactorings that move code and strand trailing `///` comments; auto-generated docs inserting comments before imports.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/7d2c8920fbc145ef. Report an issue: GitHub.

Appendix: source

Thrown at pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java:354

        return node.span();
      }
      case CLASS -> {
        var node = parseClass(header);
        nodes.add(node);
        return node.span();
      }
      case FUNCTION -> {
        var node = parseClassMethod(header);
        nodes.add(node);
        return node.span();
      }
      case EOF -> throw parserError("unexpectedEndOfFile");
      default -> {
        if (lookahead.isKeyword()) {
          throw parserError("keywordNotAllowedHere", lookahead.text());
        }
        if (lookahead == Token.DOC_COMMENT) {
          throw parserError("danglingDocComment");
        }
        throw parserError("invalidTopLevelToken");
      }
    }
  }

  private TypeAlias parseTypeAlias(MemberHeader header) {
    var typeAlias = next().span;
    var startSpan = header.span(typeAlias);

    var identifier = parseIdentifier();
    TypeParameterList typePars = null;
    if (lookahead == Token.LT) {
      typePars = parseTypeParameterList();
    }
    expect(Token.ASSIGN, "unexpectedToken", "=");
    var type = parseType();
    var children =

View on GitHub (pinned to f3efcbfc9b)