apple/pkl · error · ParserError

invalidTopLevelToken

invalidTopLevelToken

Error message

Invalid token at position. Expected a class, typealias, method, or property.

What it means

The parser encountered a token at module-member position that cannot start a class, typealias, method, or property. After ruling out keywords and doc comments, parseModuleMember throws "Invalid token at position" as the final fallback for any other unexpected token at top level.

Solutions

  1. Verify the token is at module level intentionally — most often an extra `}` closed the enclosing class/module scope early.
  2. Start members with a valid declaration: `name = expr`, `name: Type`, `function f() {...}`, `class X {}`, or `typealias Y = ...`.
  3. Move expressions inside an object body or assign them to a property.
  4. Check brace balance in the preceding code with an editor's bracket matching.

Example fix

// before (brace closed class early)
class Bird {
  name: String
}
fly = true // invalid at top level inside module member position
// after
class Bird {
  name: String
  fly = true
}
Defensive patterns

Strategy: validation

Validate before calling

// Flag top-level lines that cannot start a module member
const MEMBER_START = /^\s*(class\b|typealias\b|function\b|amends\b|extends\b|import\b|`?[A-Za-z_]\w*`?\s*(:|=|\())/;
function invalidTopLevelLines(lines) {
  return lines.map((l, i) => [l.trim(), i])
    .filter(([l]) => l && !l.startsWith('//') && !MEMBER_START.test(l))
    .map(([, i]) => i + 1);
}

Prevention

When it happens

Trigger: Statements at top level that Pkl doesn't allow (e.g. bare expressions, `new` blocks, stray `}` or `,`); object-body-only syntax like `x { ... }` amending without `=` used at module level in a way the grammar rejects; an operator or punctuation starting a line at module scope.

Common situations: Copy-pasting object-body entries outside of any object; an extra closing brace ending the enclosing class early so following members land at top level; expressions written where declarations are required.

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/481a12b72e4e9a9b. Report an issue: GitHub.

Appendix: source

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

      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 =
        new ArrayList<@Nullable Node>(header.annotations.size() + header.modifiers.size() + 5);
    children.add(header.docComment);

View on GitHub (pinned to f3efcbfc9b)