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
- Remove the orphaned `///` comment, or convert it to a plain `//` comment.
- Re-attach it directly above the class/typealias/method/property it documents (no intervening tokens).
- If it documents the module itself, place it above the module `amends`/`extends` header at the top of the file.
- 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
- Delete a `///` comment together with the declaration it documents.
- Convert explanatory-only comments to `//` instead of `///`.
- When moving code, move its doc comment with it and re-verify attachment.
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
- danglingDocComment
- invalidTopLevelToken
- invalidTopLevelToken
- keywordNotAllowedHere
- keywordNotAllowedHere
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)